From 68ad08e4487254091ca9fed217018d2698a53f60 Mon Sep 17 00:00:00 2001 From: Anders Lindh Olsson Date: Thu, 7 May 2026 14:23:13 +0200 Subject: [PATCH 1/4] fix(repository): replace ResponseStatusException with domain exceptions Repositories must not know about HTTP. Replace all ResponseStatusException throws in ChannelRepository, TagRepository, and PropertyRepository with StorageException (for ES IO failures) or the existing typed domain exceptions (ChannelValidationException for bad query windows). Add a StorageException handler to V0ExceptionHandler mapping it to 500. The NOT_FOUND status used in findById catch blocks was also wrong: those are IO/connection failures, not 404s - replaced with StorageException. --- .../exceptions/StorageException.java | 12 +++++++ .../repository/ChannelRepository.java | 34 ++++++++----------- .../repository/PropertyRepository.java | 25 ++++++-------- .../repository/TagRepository.java | 25 ++++++-------- .../web/v0/V0ExceptionHandler.java | 8 +++++ 5 files changed, 57 insertions(+), 47 deletions(-) create mode 100644 src/main/java/org/phoebus/channelfinder/exceptions/StorageException.java diff --git a/src/main/java/org/phoebus/channelfinder/exceptions/StorageException.java b/src/main/java/org/phoebus/channelfinder/exceptions/StorageException.java new file mode 100644 index 00000000..1fc968e9 --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/exceptions/StorageException.java @@ -0,0 +1,12 @@ +package org.phoebus.channelfinder.exceptions; + +public class StorageException extends RuntimeException { + + public StorageException(String message) { + super(message); + } + + public StorageException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java index 29689d2a..cd5240ff 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java @@ -57,15 +57,15 @@ import org.phoebus.channelfinder.entity.Scroll; import org.phoebus.channelfinder.entity.SearchResult; import org.phoebus.channelfinder.entity.Tag; +import org.phoebus.channelfinder.exceptions.ChannelValidationException; +import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Repository; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ResponseStatusException; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -126,7 +126,7 @@ public Channel index(Channel channel) { } catch (Exception e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_CHANNEL, channel.toLog()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } return null; } @@ -176,8 +176,7 @@ channel, new JacksonJsonpMapper(objectMapper))))) } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_CHANNELS, chunk); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } return Collections.emptyList(); })); @@ -218,7 +217,7 @@ public Channel save(String channelName, Channel channel) { } catch (Exception e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_CHANNEL, channel.toLog()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } return null; } @@ -310,8 +309,7 @@ public Iterable saveAll(Iterable channels) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_CHANNELS, channels); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } return Collections.emptyList(); })); @@ -354,7 +352,7 @@ public Optional findById(String channelName) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_FIND_CHANNEL, channelName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message, null); + throw new StorageException(message, e); } } @@ -383,8 +381,7 @@ public boolean existsByIds(List channelIds) { .containsAll(channelIds); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_CHANNELS, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_CHANNELS, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_CHANNELS, e); } } @@ -404,7 +401,7 @@ public boolean existsById(String channelName) { String message = MessageFormat.format(TextUtil.FAILED_TO_CHECK_IF_CHANNEL_EXISTS, channelName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } } @@ -440,8 +437,7 @@ public List findAllById(Iterable channelIds) { return response.hits().hits().stream().map(Hit::source).collect(Collectors.toList()); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_CHANNELS, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_CHANNELS, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_CHANNELS, e); } } @@ -468,7 +464,7 @@ public void deleteById(String channelName) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_DELETE_CHANNEL, channelName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message, e); } } @@ -527,7 +523,7 @@ public SearchResult search(MultiValueMap searchParameters) { TextUtil.SEARCH_FAILED_CAUSE, searchParameters, "Max search window exceeded, use the " + scrollResourceUri + " api."); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); + throw new ChannelValidationException(message); } try { @@ -554,7 +550,7 @@ public SearchResult search(MultiValueMap searchParameters) { String message = MessageFormat.format(TextUtil.SEARCH_FAILED_CAUSE, searchParameters, e.getMessage()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, e); + throw new StorageException(message, e); } } @@ -742,7 +738,7 @@ public long count(MultiValueMap searchParameters) { String message = MessageFormat.format(TextUtil.COUNT_FAILED_CAUSE, searchParameters, e.getMessage()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, e); + throw new StorageException(message, e); } } @@ -800,7 +796,7 @@ public Scroll scroll(String scrollId, MultiValueMap searchParame } catch (IOException | ElasticsearchException e) { String message = MessageFormat.format(TextUtil.SEARCH_FAILED_CAUSE, searchParameters, e.getMessage()); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, e); + throw new StorageException(message, e); } } diff --git a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java index 8c1792c7..01244261 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java @@ -36,15 +36,14 @@ import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.entity.Property.OnlyNameOwnerProperty; +import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Repository; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ResponseStatusException; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -108,7 +107,7 @@ public List indexAll(List properties) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_PROPERTIES, properties); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return null; } @@ -142,7 +141,7 @@ public S save(String propertyName, S property) { } catch (Exception e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_PROPERTY, property.toLog()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return null; } @@ -197,7 +196,7 @@ public Iterable saveAll(Iterable properties) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_UPDATE_SAVE_PROPERTIES, properties); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return null; } @@ -245,7 +244,7 @@ public Optional findById(String propertyName, boolean withChannels) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_FIND_PROPERTY, propertyName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message, null); + throw new StorageException(message); } } @@ -258,7 +257,7 @@ public boolean existsById(String id) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_CHECK_IF_PROPERTY_EXISTS, id); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } } @@ -280,8 +279,7 @@ public Iterable findAll() { return response.hits().hits().stream().map(Hit::source).toList(); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_PROPERTIES, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_PROPERTIES, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_PROPERTIES); } } @@ -306,8 +304,7 @@ public List findAllById(Iterable propertyIds) { return response.hits().hits().stream().map(Hit::source).toList(); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_PROPERTIES, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_PROPERTIES, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_PROPERTIES); } } @@ -322,7 +319,7 @@ public long count() { String message = MessageFormat.format(TextUtil.COUNT_FAILED_CAUSE, "", e.getMessage()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, e); + throw new StorageException(message, e); } } @@ -380,7 +377,7 @@ public void deleteById(String propertyName) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_DELETE_PROPERTY, propertyName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } params.set("~search_after", channels.get(channels.size() - 1).getName()); channels = channelRepository.search(params).channels(); @@ -388,7 +385,7 @@ public void deleteById(String propertyName) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_DELETE_PROPERTY, propertyName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } } diff --git a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java index da9ae87a..41d609c8 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java @@ -37,15 +37,14 @@ import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Tag; import org.phoebus.channelfinder.entity.Tag.OnlyTag; +import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Repository; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ResponseStatusException; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -110,7 +109,7 @@ public List indexAll(List tags) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_TAGS, tags); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return Collections.emptyList(); } @@ -141,7 +140,7 @@ public S save(String tagName, S tag) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_UPDATE_SAVE_TAG, tag.toLog()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return null; } @@ -192,7 +191,7 @@ public Iterable saveAll(Iterable tags) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_INDEX_TAGS, tags); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } return null; } @@ -236,7 +235,7 @@ public Optional findById(String tagId, boolean withChannels) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_FIND_TAG, tagId); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message, null); + throw new StorageException(message); } } @@ -249,7 +248,7 @@ public boolean existsById(String id) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_CHECK_IF_TAG_EXISTS, id); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } } @@ -271,8 +270,7 @@ public Iterable findAll() { return response.hits().hits().stream().map(Hit::source).toList(); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_TAGS, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_TAGS, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_TAGS); } } @@ -296,8 +294,7 @@ public List findAllById(Iterable tagIds) { return response.hits().hits().stream().map(Hit::source).toList(); } catch (ElasticsearchException | IOException e) { logger.log(Level.SEVERE, TextUtil.FAILED_TO_FIND_ALL_TAGS, e); - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, TextUtil.FAILED_TO_FIND_ALL_TAGS, null); + throw new StorageException(TextUtil.FAILED_TO_FIND_ALL_TAGS); } } @@ -312,7 +309,7 @@ public long count() { String message = MessageFormat.format(TextUtil.COUNT_FAILED_CAUSE, "", e.getMessage()); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, e); + throw new StorageException(message, e); } } @@ -367,7 +364,7 @@ public void deleteById(String tagName) { } catch (IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_DELETE_TAG, tagName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } params.set("~search_after", channels.get(channels.size() - 1).getName()); channels = channelRepository.search(params).channels(); @@ -376,7 +373,7 @@ public void deleteById(String tagName) { } catch (ElasticsearchException | IOException e) { String message = MessageFormat.format(TextUtil.FAILED_TO_DELETE_TAG, tagName); logger.log(Level.SEVERE, message, e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, message, null); + throw new StorageException(message); } } diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/V0ExceptionHandler.java b/src/main/java/org/phoebus/channelfinder/web/v0/V0ExceptionHandler.java index ef3e3a17..f92db4ef 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/V0ExceptionHandler.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/V0ExceptionHandler.java @@ -6,6 +6,7 @@ import org.phoebus.channelfinder.exceptions.ChannelValidationException; import org.phoebus.channelfinder.exceptions.PropertyNotFoundException; import org.phoebus.channelfinder.exceptions.PropertyValidationException; +import org.phoebus.channelfinder.exceptions.StorageException; import org.phoebus.channelfinder.exceptions.TagNotFoundException; import org.phoebus.channelfinder.exceptions.TagValidationException; import org.phoebus.channelfinder.exceptions.UnauthorizedException; @@ -86,6 +87,13 @@ public ResponseStatusException handleMessageNotReadable(HttpMessageNotReadableEx return new ResponseStatusException(HttpStatus.BAD_REQUEST, "Malformed request body"); } + @ExceptionHandler(StorageException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ResponseStatusException handleStorage(StorageException ex) { + logger.log(Level.SEVERE, ex.getMessage(), ex); + return new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage()); + } + @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ResponseStatusException handleUnexpected(Exception ex) { From 2def99595b9ec9c7e8cc1d8d37e1e1eb3e8a5d84 Mon Sep 17 00:00:00 2001 From: Anders Lindh Olsson Date: Thu, 7 May 2026 14:29:09 +0200 Subject: [PATCH 2/4] refactor(service): remove Spring MultiValueMap from service and repository boundaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Services should preferably not depend on Spring types. Replace MultiValueMap with Map> in all service method signatures and repository public APIs. Controllers pass their MultiValueMap directly — no conversion needed since MultiValueMap IS a Map>. Also replaces internal LinkedMultiValueMap usages in TagRepository and PropertyRepository scroll loops, MetricsService metric-combination generation, ChannelProcessorService.processAllChannels, and ChannelFinderEpicsService with standard java.util equivalents. --- .../repository/ChannelRepository.java | 20 +++---- .../repository/PropertyRepository.java | 15 +++-- .../repository/TagRepository.java | 15 +++-- .../service/ChannelFinderEpicsService.java | 5 +- .../service/ChannelProcessorService.java | 10 ++-- .../service/ChannelScrollService.java | 5 +- .../channelfinder/service/ChannelService.java | 7 +-- .../channelfinder/service/MetricsService.java | 56 ++++++++----------- .../channelfinder/MetricsServiceTest.java | 41 +++----------- 9 files changed, 67 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java index cd5240ff..f499c484 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java @@ -64,8 +64,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -443,7 +441,7 @@ public List findAllById(Iterable channelIds) { @Override public long count() { - return this.count(new LinkedMultiValueMap<>()); + return this.count(Map.of()); } /** @@ -512,7 +510,7 @@ public void deleteAll() { * @param searchParameters channel search parameters * @return matching channels */ - public SearchResult search(MultiValueMap searchParameters) { + public SearchResult search(Map> searchParameters) { BuiltQuery builtQuery = getBuiltQuery(searchParameters); Integer finalSize = builtQuery.size; Integer finalFrom = builtQuery.from; @@ -554,7 +552,7 @@ public SearchResult search(MultiValueMap searchParameters) { } } - private BuiltQuery getBuiltQuery(MultiValueMap searchParameters) { + private BuiltQuery getBuiltQuery(Map> searchParameters) { BoolQuery.Builder boolQuery = new BoolQuery.Builder(); int size = esService.getES_QUERY_SIZE(); int from = 0; @@ -722,7 +720,7 @@ private record BuiltQuery( * @param searchParameters channel search parameters * @return count of the number of matches to the provided query */ - public long count(MultiValueMap searchParameters) { + public long count(Map> searchParameters) { BuiltQuery builtQuery = getBuiltQuery(searchParameters); try { @@ -750,9 +748,7 @@ public long count(MultiValueMap searchParameters) { * @return count of the number of matches to the provided query */ public long countByProperty(String propertyName, String propertyValue) { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(propertyName, propertyValue == null ? "*" : propertyValue); - return this.count(params); + return this.count(Map.of(propertyName, List.of(propertyValue == null ? "*" : propertyValue))); } /** @@ -762,9 +758,7 @@ public long countByProperty(String propertyName, String propertyValue) { * @return count of the number of matches to the provided query */ public long countByTag(String tagName) { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("~tag", tagName); - return this.count(params); + return this.count(Map.of("~tag", List.of(tagName))); } /** @@ -775,7 +769,7 @@ public long countByTag(String tagName) { * @param searchParameters channel search parameters * @return next page with its cursor */ - public Scroll scroll(String scrollId, MultiValueMap searchParameters) { + public Scroll scroll(String scrollId, Map> searchParameters) { BuiltQuery builtQuery = getBuiltQuery(searchParameters); try { SearchRequest.Builder builder = diff --git a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java index 01244261..8364f699 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java @@ -26,7 +26,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.text.MessageFormat; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,8 +44,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -231,9 +231,8 @@ public Optional findById(String propertyName, boolean withChannels) { logger.log( Level.CONFIG, () -> MessageFormat.format(TextUtil.PROPERTY_FOUND, property.getName())); if (withChannels) { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(property.getName(), "*"); - property.setChannels(channelRepository.search(params).channels()); + property.setChannels( + channelRepository.search(Map.of(property.getName(), List.of("*"))).channels()); } return Optional.of(property); } else { @@ -343,8 +342,8 @@ public void deleteById(String propertyName) { // Remove the Property from Channels BulkRequest.Builder br = new BulkRequest.Builder().refresh(Refresh.True); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(propertyName, "*"); + Map> params = new LinkedHashMap<>(); + params.put(propertyName, List.of("*")); List channels = channelRepository.search(params).channels(); while (channels.size() > 0) { for (Channel channel : channels) { @@ -379,7 +378,7 @@ public void deleteById(String propertyName) { logger.log(Level.SEVERE, message, e); throw new StorageException(message); } - params.set("~search_after", channels.get(channels.size() - 1).getName()); + params.put("~search_after", List.of(channels.get(channels.size() - 1).getName())); channels = channelRepository.search(params).channels(); } } catch (ElasticsearchException | IOException e) { diff --git a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java index 41d609c8..d775e31b 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java @@ -27,7 +27,9 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,8 +45,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @@ -223,9 +223,8 @@ public Optional findById(String tagId, boolean withChannels) { Tag tag = response.source(); logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.TAG_FOUND, tag.getName())); if (withChannels) { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("~tag", tag.getName()); - tag.setChannels(channelRepository.search(params).channels()); + tag.setChannels( + channelRepository.search(Map.of("~tag", List.of(tag.getName()))).channels()); } return Optional.of(tag); } else { @@ -330,8 +329,8 @@ public void deleteById(String tagName) { logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.DELETE_TAG, tagName)); } BulkRequest.Builder br = new BulkRequest.Builder().refresh(Refresh.True); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("~tag", tagName); + Map> params = new LinkedHashMap<>(); + params.put("~tag", List.of(tagName)); List channels = channelRepository.search(params).channels(); while (!channels.isEmpty()) { @@ -366,7 +365,7 @@ public void deleteById(String tagName) { logger.log(Level.SEVERE, message, e); throw new StorageException(message); } - params.set("~search_after", channels.get(channels.size() - 1).getName()); + params.put("~search_after", List.of(channels.get(channels.size() - 1).getName())); channels = channelRepository.search(params).channels(); } diff --git a/src/main/java/org/phoebus/channelfinder/service/ChannelFinderEpicsService.java b/src/main/java/org/phoebus/channelfinder/service/ChannelFinderEpicsService.java index d553b0a1..4c693927 100644 --- a/src/main/java/org/phoebus/channelfinder/service/ChannelFinderEpicsService.java +++ b/src/main/java/org/phoebus/channelfinder/service/ChannelFinderEpicsService.java @@ -4,6 +4,7 @@ import jakarta.annotation.PreDestroy; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -24,8 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; /** * A pva RPC service for channelfinder @@ -106,7 +105,7 @@ public HandlerQuery(PVAStructure args, ChannelRepository channelRepository) { public PVAStructure run() throws MustBeArrayException { - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + Map> searchParameters = new LinkedHashMap<>(); PVAURI uri = PVAURI.fromStructure(args); Map query; try { diff --git a/src/main/java/org/phoebus/channelfinder/service/ChannelProcessorService.java b/src/main/java/org/phoebus/channelfinder/service/ChannelProcessorService.java index 846b9684..e13ce37f 100644 --- a/src/main/java/org/phoebus/channelfinder/service/ChannelProcessorService.java +++ b/src/main/java/org/phoebus/channelfinder/service/ChannelProcessorService.java @@ -1,7 +1,9 @@ package org.phoebus.channelfinder.service; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Spliterator; @@ -20,8 +22,6 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; @Service public class ChannelProcessorService { @@ -57,12 +57,12 @@ public long processAllChannels() { "User does not have the proper authorization to perform this operation: /process/all"); } logger.log(Level.INFO, "Calling processor on ALL channels in ChannelFinder"); - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - searchParameters.add("~name", "*"); + Map> searchParameters = new LinkedHashMap<>(); + searchParameters.put("~name", List.of("*")); return processChannelsByQuery(searchParameters); } - public long processChannelsByQuery(MultiValueMap allRequestParams) { + public long processChannelsByQuery(Map> allRequestParams) { long channelCount = 0; Scroll scrollResult = channelScrollService.search(null, allRequestParams); channelCount += scrollResult.getChannels().size(); diff --git a/src/main/java/org/phoebus/channelfinder/service/ChannelScrollService.java b/src/main/java/org/phoebus/channelfinder/service/ChannelScrollService.java index 68369ace..3ae08cbb 100644 --- a/src/main/java/org/phoebus/channelfinder/service/ChannelScrollService.java +++ b/src/main/java/org/phoebus/channelfinder/service/ChannelScrollService.java @@ -1,9 +1,10 @@ package org.phoebus.channelfinder.service; +import java.util.List; +import java.util.Map; import org.phoebus.channelfinder.entity.Scroll; import org.phoebus.channelfinder.repository.ChannelRepository; import org.springframework.stereotype.Service; -import org.springframework.util.MultiValueMap; @Service public class ChannelScrollService { @@ -14,7 +15,7 @@ public ChannelScrollService(ChannelRepository channelRepository) { this.channelRepository = channelRepository; } - public Scroll search(String scrollId, MultiValueMap searchParameters) { + public Scroll search(String scrollId, Map> searchParameters) { return channelRepository.scroll(scrollId, searchParameters); } } diff --git a/src/main/java/org/phoebus/channelfinder/service/ChannelService.java b/src/main/java/org/phoebus/channelfinder/service/ChannelService.java index c3b874fc..0fadcbe6 100644 --- a/src/main/java/org/phoebus/channelfinder/service/ChannelService.java +++ b/src/main/java/org/phoebus/channelfinder/service/ChannelService.java @@ -25,7 +25,6 @@ import org.phoebus.channelfinder.service.AuthorizationService.ROLES; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; -import org.springframework.util.MultiValueMap; @Service public class ChannelService { @@ -52,15 +51,15 @@ public ChannelService( this.channelProcessorService = channelProcessorService; } - public List query(MultiValueMap allRequestParams) { + public List query(Map> allRequestParams) { return channelRepository.search(allRequestParams).channels(); } - public SearchResult combinedQuery(MultiValueMap allRequestParams) { + public SearchResult combinedQuery(Map> allRequestParams) { return channelRepository.search(allRequestParams); } - public long queryCount(MultiValueMap allRequestParams) { + public long queryCount(Map> allRequestParams) { return channelRepository.count(allRequestParams); } diff --git a/src/main/java/org/phoebus/channelfinder/service/MetricsService.java b/src/main/java/org/phoebus/channelfinder/service/MetricsService.java index e064d4a9..9e5cc3c4 100644 --- a/src/main/java/org/phoebus/channelfinder/service/MetricsService.java +++ b/src/main/java/org/phoebus/channelfinder/service/MetricsService.java @@ -7,6 +7,7 @@ import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -20,8 +21,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; @Service public class MetricsService { @@ -46,7 +45,7 @@ public class MetricsService { private final TagRepository tagRepository; private final MeterRegistry meterRegistry; - private Map, AtomicLong> propertyMetrics; + private Map>, AtomicLong> propertyMetrics; private Map tagMetrics; @Value("${metrics.tags}") @@ -84,8 +83,7 @@ public MetricsService( @PostConstruct private void registerGaugeMetrics() { - Gauge.builder( - CF_TOTAL_CHANNEL_COUNT, () -> channelRepository.count(new LinkedMultiValueMap<>())) + Gauge.builder(CF_TOTAL_CHANNEL_COUNT, () -> channelRepository.count(Map.of())) .description(METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT) .register(meterRegistry); Gauge.builder(CF_PROPERTY_COUNT, propertyRepository::count) @@ -113,28 +111,28 @@ private void registerTagMetrics() { } } - public static List> generateAllMultiValueMaps( + public static List>> generateAllMultiValueMaps( Map> properties) { - List> allMultiValueMaps = new ArrayList<>(); + List>> allQueryParams = new ArrayList<>(); if (properties.isEmpty()) { return List.of(); } List>> entries = new ArrayList<>(properties.entrySet()); - generateCombinations(entries, 0, new LinkedMultiValueMap<>(), allMultiValueMaps); + generateCombinations(entries, 0, new LinkedHashMap<>(), allQueryParams); - return allMultiValueMaps; + return allQueryParams; } private static void generateCombinations( List>> entries, int index, - MultiValueMap currentMap, - List> allMultiValueMaps) { + Map> currentMap, + List>> allQueryParams) { if (index == entries.size()) { - allMultiValueMaps.add(new LinkedMultiValueMap<>(currentMap)); + allQueryParams.add(new LinkedHashMap<>(currentMap)); return; } @@ -142,33 +140,27 @@ private static void generateCombinations( String key = currentEntry.getKey(); List values = currentEntry.getValue(); - // Add the other options for (String value : values) { - LinkedMultiValueMap nextMapWithValue = new LinkedMultiValueMap<>(currentMap); + Map> nextMap = new LinkedHashMap<>(currentMap); if (value.startsWith(NEGATE)) { - nextMapWithValue.add(key + NEGATE, value.substring(1)); + nextMap.computeIfAbsent(key + NEGATE, k -> new ArrayList<>()).add(value.substring(1)); } else { - nextMapWithValue.add(key, value); + nextMap.computeIfAbsent(key, k -> new ArrayList<>()).add(value); } - generateCombinations(entries, index + 1, nextMapWithValue, allMultiValueMaps); + generateCombinations(entries, index + 1, nextMap, allQueryParams); } } - private List metricTagsFromMultiValueMap(MultiValueMap multiValueMap) { + private List metricTagsFrom(Map> queryParams) { List metricTags = new ArrayList<>(); - for (Map.Entry entry : multiValueMap.toSingleValueMap().entrySet()) { + for (Map.Entry> entry : queryParams.entrySet()) { + String firstValue = entry.getValue().isEmpty() ? "" : entry.getValue().get(0); if (entry.getKey().endsWith(NEGATE)) { - if (entry.getValue().equals("*")) { - metricTags.add( - new ImmutableTag(entry.getKey().substring(0, entry.getKey().length() - 1), NOT_SET)); - } else { - metricTags.add( - new ImmutableTag( - entry.getKey().substring(0, entry.getKey().length() - 1), - NEGATE + entry.getValue())); - } + String tagKey = entry.getKey().substring(0, entry.getKey().length() - 1); + metricTags.add( + new ImmutableTag(tagKey, firstValue.equals("*") ? NOT_SET : NEGATE + firstValue)); } else { - metricTags.add(new ImmutableTag(entry.getKey(), entry.getValue())); + metricTags.add(new ImmutableTag(entry.getKey(), firstValue)); } } return metricTags; @@ -177,7 +169,7 @@ private List metricTagsFromMultiValueMap(MultiValueMap mult private void registerPropertyMetrics() { Map> properties = parseProperties(); - List> combinations = generateAllMultiValueMaps(properties); + List>> combinations = generateAllMultiValueMaps(properties); propertyMetrics = combinations.stream() @@ -187,7 +179,7 @@ private void registerPropertyMetrics() { map -> Gauge.builder(CF_CHANNEL_COUNT, propertyMetrics, m -> m.get(map).doubleValue()) .description(METRIC_DESCRIPTION_CHANNEL_COUNT) - .tags(metricTagsFromMultiValueMap(map)) + .tags(metricTagsFrom(map)) .register(meterRegistry)); } @@ -198,7 +190,7 @@ private void updateTagMetrics() { } private void updatePropertyMetrics() { - for (Map.Entry, AtomicLong> propertyMetricEntry : + for (Map.Entry>, AtomicLong> propertyMetricEntry : propertyMetrics.entrySet()) { propertyMetricEntry.getValue().set(channelRepository.count(propertyMetricEntry.getKey())); } diff --git a/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java b/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java index 1bd55dbb..3f993634 100644 --- a/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java +++ b/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java @@ -7,8 +7,6 @@ import java.util.Map; import org.junit.jupiter.api.Test; import org.phoebus.channelfinder.service.MetricsService; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; class MetricsServiceTest { @@ -18,8 +16,7 @@ void testGenerateAllMultiValueMaps_example1() { Map.of( "a", List.of("b", "c"), "d", List.of("e", "!*")); - List> allMaps = - MetricsService.generateAllMultiValueMaps(properties); + List>> allMaps = MetricsService.generateAllMultiValueMaps(properties); assertEquals(4, allMaps.size()); @@ -36,14 +33,12 @@ void testGenerateAllMultiValueMaps_example2() { "x", List.of("y", "z"), "p", List.of("q"), "r", List.of("s", "t")); - List> allMaps = - MetricsService.generateAllMultiValueMaps(properties); + List>> allMaps = MetricsService.generateAllMultiValueMaps(properties); - assertEquals(2 * 2, allMaps.size()); // 2 options (value or null) for each of 2 keys + assertEquals(2 * 2, allMaps.size()); - // Just a basic check, exhaustive check would be large boolean foundExpectedCombination = false; - for (MultiValueMap map : allMaps) { + for (Map> map : allMaps) { if (map.get("x").contains("y") && map.get("p").contains("q") && map.get("r").contains("s")) { foundExpectedCombination = true; break; @@ -55,39 +50,21 @@ void testGenerateAllMultiValueMaps_example2() { @Test void testGenerateAllMultiValueMaps_emptyList() { Map> properties = Map.of("m", List.of()); - List> allMaps = - MetricsService.generateAllMultiValueMaps(properties); + List>> allMaps = MetricsService.generateAllMultiValueMaps(properties); - assertEquals(0, allMaps.size()); // One with m=null, one with m implicitly null (not present) + assertEquals(0, allMaps.size()); } @Test void testGenerateAllMultiValueMaps_emptyMap() { Map> properties = Map.of(); - List> allMaps = - MetricsService.generateAllMultiValueMaps(properties); + List>> allMaps = MetricsService.generateAllMultiValueMaps(properties); assertEquals(0, allMaps.size()); } - // Helper method to create a MultiValueMap for easier assertion - private MultiValueMap createMap( + private Map> createMap( String key1, String value1, String key2, String value2) { - LinkedMultiValueMap map = new LinkedMultiValueMap<>(); - if (key1 != null) { - map.add(key1, value1); - } - if (key2 != null) { - map.add(key2, value2); - } - return map; - } - - private MultiValueMap createMap(String key, String value) { - LinkedMultiValueMap map = new LinkedMultiValueMap<>(); - if (key != null) { - map.add(key, value); - } - return map; + return Map.of(key1, List.of(value1), key2, List.of(value2)); } } From 074f9d63f2646dde2fc98f5d7fe913aeadb110c8 Mon Sep 17 00:00:00 2001 From: Anders Lindh Olsson Date: Thu, 7 May 2026 14:30:48 +0200 Subject: [PATCH 3/4] fix(repository): remove spurious @Configuration from repository classes @Repository and @Configuration must not be combined on the same class. The @Configuration annotation was causing repositories to participate in Spring's configuration processing, which is incorrect. Remove it from all three repositories and drop the now-unused import. --- .../org/phoebus/channelfinder/repository/ChannelRepository.java | 2 -- .../phoebus/channelfinder/repository/PropertyRepository.java | 2 -- .../org/phoebus/channelfinder/repository/TagRepository.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java index f499c484..0c77bc21 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java @@ -61,14 +61,12 @@ import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @Repository -@Configuration public class ChannelRepository implements CrudRepository { private static final Logger logger = Logger.getLogger(ChannelRepository.class.getName()); diff --git a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java index 8364f699..f4ba7445 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java @@ -41,14 +41,12 @@ import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @Repository -@Configuration public class PropertyRepository implements CrudRepository { private static final Logger logger = Logger.getLogger(PropertyRepository.class.getName()); diff --git a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java index d775e31b..8649b954 100644 --- a/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java +++ b/src/main/java/org/phoebus/channelfinder/repository/TagRepository.java @@ -42,14 +42,12 @@ import org.phoebus.channelfinder.exceptions.StorageException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; // Jackson 2 required by elasticsearch-java 8.x JacksonJsonpMapper — migrate with ES 9 @Repository -@Configuration public class TagRepository implements CrudRepository { private static final Logger logger = Logger.getLogger(TagRepository.class.getName()); From 6c441095b0022c140faf632ee7370f1ee5ab8e34 Mon Sep 17 00:00:00 2001 From: Anders Lindh Olsson Date: Thu, 7 May 2026 15:10:37 +0200 Subject: [PATCH 4/4] refactor(web/v0): introduce DTO layer at the controller boundary Add ChannelDto, TagDto, PropertyDto, SearchResultDto, ScrollDto under web/v0/dto/ and corresponding static mappers under web/v0/mapper/. All five controllers now map to/from DTOs; the service and domain layers are unchanged. This isolates the v0 API shape from the domain model so a future v1 API can evolve its own DTOs without touching service or repository code. --- .../service/PropertyService.java | 2 +- .../channelfinder/web/v0/api/IChannel.java | 37 ++--- .../web/v0/api/IChannelProcessor.java | 4 +- .../web/v0/api/IChannelScroll.java | 10 +- .../channelfinder/web/v0/api/IProperty.java | 38 ++--- .../channelfinder/web/v0/api/ITag.java | 33 +++-- .../web/v0/controller/ChannelController.java | 35 ++--- .../ChannelProcessorController.java | 7 +- .../controller/ChannelScrollController.java | 16 ++- .../web/v0/controller/PropertyController.java | 34 +++-- .../web/v0/controller/TagController.java | 31 ++-- .../channelfinder/web/v0/dto/ChannelDto.java | 17 +++ .../channelfinder/web/v0/dto/PropertyDto.java | 15 ++ .../channelfinder/web/v0/dto/ScrollDto.java | 5 + .../web/v0/dto/SearchResultDto.java | 5 + .../channelfinder/web/v0/dto/TagDto.java | 15 ++ .../web/v0/mapper/ChannelMapper.java | 36 +++++ .../web/v0/mapper/PropertyMapper.java | 39 +++++ .../web/v0/mapper/TagMapper.java | 37 +++++ .../channelfinder/ChannelControllerIT.java | 83 +++++++---- .../ChannelScrollControllerIT.java | 73 +++++----- .../ChannelScrollControllerSearchIT.java | 44 +++--- .../channelfinder/PropertyControllerIT.java | 135 +++++++++++------- .../channelfinder/TagControllerIT.java | 123 +++++++++------- .../epics/EpicsRPCRequestIT.java | 10 +- 25 files changed, 579 insertions(+), 305 deletions(-) create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/dto/ChannelDto.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/dto/PropertyDto.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/dto/ScrollDto.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/dto/SearchResultDto.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/dto/TagDto.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/mapper/ChannelMapper.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/mapper/PropertyMapper.java create mode 100644 src/main/java/org/phoebus/channelfinder/web/v0/mapper/TagMapper.java diff --git a/src/main/java/org/phoebus/channelfinder/service/PropertyService.java b/src/main/java/org/phoebus/channelfinder/service/PropertyService.java index 95dfd95b..d9e6614c 100644 --- a/src/main/java/org/phoebus/channelfinder/service/PropertyService.java +++ b/src/main/java/org/phoebus/channelfinder/service/PropertyService.java @@ -157,7 +157,7 @@ public Property update(String propertyName, Property property) { propagateRenameToChannels(propertyName, updated, chans); if (!property.getChannels().isEmpty()) { - List chanList = saveAndRetainProperty(property.getChannels(), propertyName); + List chanList = saveAndRetainProperty(property.getChannels(), updated.getName()); if (!chanList.isEmpty()) updated.setChannels(chanList); } diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannel.java b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannel.java index 4295d710..88c7197c 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannel.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannel.java @@ -10,8 +10,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import java.util.List; -import org.phoebus.channelfinder.entity.Channel; -import org.phoebus.channelfinder.entity.SearchResult; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.dto.SearchResultDto; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -36,7 +36,8 @@ public interface IChannel { responseCode = "200", description = "List of channels", content = - @Content(array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), + @Content( + array = @ArraySchema(schema = @Schema(implementation = ChannelDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -47,7 +48,7 @@ public interface IChannel { content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping - List query( + List query( @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam MultiValueMap allRequestParams); @@ -64,7 +65,8 @@ List query( description = "The number of matches for the query, and the first 10k channels", content = @Content( - array = @ArraySchema(schema = @Schema(implementation = SearchResult.class)))), + array = + @ArraySchema(schema = @Schema(implementation = SearchResultDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request - response size exceeded", @@ -75,7 +77,7 @@ List query( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping("/combined") - SearchResult combinedQuery( + SearchResultDto combinedQuery( @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam MultiValueMap allRequestParams); @@ -110,14 +112,14 @@ long queryCount( @ApiResponse( responseCode = "200", description = "Channel with the specified name", - content = @Content(schema = @Schema(implementation = Channel.class))), + content = @Content(schema = @Schema(implementation = ChannelDto.class))), @ApiResponse( responseCode = "404", description = "Channel not found", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping("/{channelName}") - Channel read(@PathVariable("channelName") String channelName); + ChannelDto read(@PathVariable("channelName") String channelName); @Operation( summary = "Create or replace a channel", @@ -129,7 +131,7 @@ long queryCount( @ApiResponse( responseCode = "200", description = "The created/replaced channel", - content = @Content(schema = @Schema(implementation = Channel.class))), + content = @Content(schema = @Schema(implementation = ChannelDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -148,7 +150,8 @@ long queryCount( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping("/{channelName}") - Channel create(@PathVariable("channelName") String channelName, @RequestBody Channel channel); + ChannelDto create( + @PathVariable("channelName") String channelName, @RequestBody ChannelDto channel); @Operation( summary = "Create or replace multiple channels", @@ -161,7 +164,8 @@ long queryCount( responseCode = "200", description = "The created/replaced channels", content = - @Content(array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), + @Content( + array = @ArraySchema(schema = @Schema(implementation = ChannelDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -180,7 +184,7 @@ long queryCount( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping - Iterable create(@RequestBody Iterable channels); + Iterable create(@RequestBody Iterable channels); @Operation( summary = "Update a channel", @@ -193,7 +197,7 @@ long queryCount( @ApiResponse( responseCode = "200", description = "The updated channel", - content = @Content(schema = @Schema(implementation = Channel.class))), + content = @Content(schema = @Schema(implementation = ChannelDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -212,7 +216,8 @@ long queryCount( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping("/{channelName}") - Channel update(@PathVariable("channelName") String channelName, @RequestBody Channel channel); + ChannelDto update( + @PathVariable("channelName") String channelName, @RequestBody ChannelDto channel); @Operation( summary = "Update multiple channels", @@ -225,7 +230,7 @@ long queryCount( @ApiResponse( responseCode = "200", description = "The updated channels", - content = @Content(schema = @Schema(implementation = Channel.class))), + content = @Content(schema = @Schema(implementation = ChannelDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -244,7 +249,7 @@ long queryCount( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping() - Iterable update(@RequestBody Iterable channels); + Iterable update(@RequestBody Iterable channels); @Operation( summary = "Delete a channel", diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelProcessor.java b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelProcessor.java index 417a02b9..e8178040 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelProcessor.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelProcessor.java @@ -10,8 +10,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import java.util.List; -import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.service.model.archiver.ChannelProcessorInfo; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -92,7 +92,7 @@ long processChannels( MultiValueMap allRequestParams); @PutMapping("/process/channels") - void processChannels(List channels); + void processChannels(List channels); @Operation(summary = "Set if the processor is enabled or not") @PutMapping( diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelScroll.java b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelScroll.java index f0a77e4e..ccc7de93 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelScroll.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/api/IChannelScroll.java @@ -7,7 +7,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.phoebus.channelfinder.common.CFResourceDescriptors; -import org.phoebus.channelfinder.entity.Scroll; +import org.phoebus.channelfinder.web.v0.dto.ScrollDto; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -26,14 +26,14 @@ public interface IChannelScroll { @ApiResponse( responseCode = "200", description = "Scroll that contains a collection of channel instances", - content = @Content(schema = @Schema(implementation = Scroll.class))), + content = @Content(schema = @Schema(implementation = ScrollDto.class))), @ApiResponse( responseCode = "500", description = "Error while trying to list channels", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping - Scroll query( + ScrollDto query( @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) @RequestParam MultiValueMap allRequestParams); @@ -48,14 +48,14 @@ Scroll query( @ApiResponse( responseCode = "200", description = "Scroll List of channels", - content = @Content(schema = @Schema(implementation = Scroll.class))), + content = @Content(schema = @Schema(implementation = ScrollDto.class))), @ApiResponse( responseCode = "500", description = "Error while trying to list channels", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping("/{scrollId}") - Scroll query( + ScrollDto query( @Parameter(description = "Scroll ID from previous query") @PathVariable("scrollId") String scrollId, @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) @RequestParam diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/api/IProperty.java b/src/main/java/org/phoebus/channelfinder/web/v0/api/IProperty.java index a6b707ac..e5757774 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/api/IProperty.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/api/IProperty.java @@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import org.phoebus.channelfinder.entity.Property; +import org.phoebus.channelfinder.web.v0.dto.PropertyDto; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -29,14 +29,15 @@ public interface IProperty { responseCode = "200", description = "List of properties", content = - @Content(array = @ArraySchema(schema = @Schema(implementation = Property.class)))), + @Content( + array = @ArraySchema(schema = @Schema(implementation = PropertyDto.class)))), @ApiResponse( responseCode = "500", description = "Error while listing properties", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping - Iterable list(); + Iterable list(); @Operation( summary = "Get property by name", @@ -48,14 +49,14 @@ public interface IProperty { @ApiResponse( responseCode = "200", description = "Fetch property by propertyName", - content = @Content(schema = @Schema(implementation = Property.class))), + content = @Content(schema = @Schema(implementation = PropertyDto.class))), @ApiResponse( responseCode = "404", description = "Property not found", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping("/{propertyName}") - Property read( + PropertyDto read( @PathVariable("propertyName") String propertyName, @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels); @@ -69,7 +70,7 @@ Property read( @ApiResponse( responseCode = "200", description = "Property created", - content = @Content(schema = @Schema(implementation = Property.class))), + content = @Content(schema = @Schema(implementation = PropertyDto.class))), @ApiResponse( responseCode = "401", description = "Unauthorized", @@ -84,8 +85,8 @@ Property read( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping("/{propertyName}") - Property create( - @PathVariable("propertyName") String propertyName, @RequestBody Property property); + PropertyDto create( + @PathVariable("propertyName") String propertyName, @RequestBody PropertyDto property); @Operation( summary = "Create multiple properties", @@ -97,7 +98,7 @@ Property create( @ApiResponse( responseCode = "200", description = "Properties created", - content = @Content(schema = @Schema(implementation = Property.class))), + content = @Content(schema = @Schema(implementation = PropertyDto.class))), @ApiResponse( responseCode = "401", description = "Unauthorized", @@ -108,7 +109,7 @@ Property create( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping() - Iterable create(@RequestBody Iterable properties); + Iterable create(@RequestBody Iterable properties); @Operation( summary = "Add property to a single channel", @@ -121,7 +122,7 @@ Property create( @ApiResponse( responseCode = "200", description = "Property added to the channel", - content = @Content(schema = @Schema(implementation = Property.class))), + content = @Content(schema = @Schema(implementation = PropertyDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -140,10 +141,10 @@ Property create( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping("/{propertyName}/{channelName}") - Property addSingle( + PropertyDto addSingle( @PathVariable("propertyName") String propertyName, @PathVariable("channelName") String channelName, - @RequestBody Property property); + @RequestBody PropertyDto property); @Operation( summary = "Update a property", @@ -156,7 +157,7 @@ Property addSingle( @ApiResponse( responseCode = "200", description = "Property updated", - content = @Content(schema = @Schema(implementation = Property.class))), + content = @Content(schema = @Schema(implementation = PropertyDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -175,8 +176,8 @@ Property addSingle( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping("/{propertyName}") - Property update( - @PathVariable("propertyName") String propertyName, @RequestBody Property property); + PropertyDto update( + @PathVariable("propertyName") String propertyName, @RequestBody PropertyDto property); @Operation( summary = "Update multiple properties", @@ -189,7 +190,8 @@ Property update( responseCode = "200", description = "Properties updated", content = - @Content(array = @ArraySchema(schema = @Schema(implementation = Property.class)))), + @Content( + array = @ArraySchema(schema = @Schema(implementation = PropertyDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -208,7 +210,7 @@ Property update( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping() - Iterable update(@RequestBody Iterable properties); + Iterable update(@RequestBody Iterable properties); @Operation( summary = "Delete a property", diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/api/ITag.java b/src/main/java/org/phoebus/channelfinder/web/v0/api/ITag.java index efe63431..8f8401f5 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/api/ITag.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/api/ITag.java @@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import org.phoebus.channelfinder.entity.Tag; +import org.phoebus.channelfinder.web.v0.dto.TagDto; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -28,14 +28,15 @@ public interface ITag { @ApiResponse( responseCode = "200", description = "List all Tags", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = TagDto.class)))), @ApiResponse( responseCode = "500", description = "Error while trying to list all Tags", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping - Iterable list(); + Iterable list(); @Operation( summary = "Get tag by name", @@ -47,14 +48,14 @@ public interface ITag { @ApiResponse( responseCode = "200", description = "Finding Tag by tagName", - content = @Content(schema = @Schema(implementation = Tag.class))), + content = @Content(schema = @Schema(implementation = TagDto.class))), @ApiResponse( responseCode = "404", description = "Tag not found", content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @GetMapping("/{tagName}") - Tag read( + TagDto read( @PathVariable("tagName") String tagName, @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels); @@ -68,7 +69,7 @@ Tag read( @ApiResponse( responseCode = "200", description = "Tag created and updated", - content = @Content(schema = @Schema(implementation = Tag.class))), + content = @Content(schema = @Schema(implementation = TagDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -87,7 +88,7 @@ Tag read( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping("/{tagName}") - Tag create(@PathVariable("tagName") String tagName, @RequestBody Tag tag); + TagDto create(@PathVariable("tagName") String tagName, @RequestBody TagDto tag); @Operation( summary = "Create multiple tags", @@ -99,7 +100,8 @@ Tag read( @ApiResponse( responseCode = "200", description = "Tags created", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = TagDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -118,7 +120,7 @@ Tag read( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping() - Iterable create(@RequestBody Iterable tags); + Iterable create(@RequestBody Iterable tags); @Operation( summary = "Add tag to a single channel", @@ -130,7 +132,7 @@ Tag read( @ApiResponse( responseCode = "200", description = "Tags added to a single channel", - content = @Content(schema = @Schema(implementation = Tag.class))), + content = @Content(schema = @Schema(implementation = TagDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -149,7 +151,7 @@ Tag read( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PutMapping("/{tagName}/{channelName}") - Tag addSingle( + TagDto addSingle( @PathVariable("tagName") String tagName, @PathVariable("channelName") String channelName); @Operation( @@ -163,7 +165,7 @@ Tag addSingle( @ApiResponse( responseCode = "200", description = "Tag updated", - content = @Content(schema = @Schema(implementation = Tag.class))), + content = @Content(schema = @Schema(implementation = TagDto.class))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -182,7 +184,7 @@ Tag addSingle( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping("/{tagName}") - Tag update(@PathVariable("tagName") String tagName, @RequestBody Tag tag); + TagDto update(@PathVariable("tagName") String tagName, @RequestBody TagDto tag); @Operation( summary = "Update multiple tags", @@ -195,7 +197,8 @@ Tag addSingle( @ApiResponse( responseCode = "200", description = "Tags updated", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = TagDto.class)))), @ApiResponse( responseCode = "400", description = "Invalid request", @@ -214,7 +217,7 @@ Tag addSingle( content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) }) @PostMapping() - Iterable update(@RequestBody Iterable tags); + Iterable update(@RequestBody Iterable tags); @Operation( summary = "Delete a tag", diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelController.java b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelController.java index ab094ad1..52ec8b2c 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelController.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelController.java @@ -1,10 +1,11 @@ package org.phoebus.channelfinder.web.v0.controller; import java.util.List; -import org.phoebus.channelfinder.entity.Channel; -import org.phoebus.channelfinder.entity.SearchResult; import org.phoebus.channelfinder.service.ChannelService; import org.phoebus.channelfinder.web.v0.api.IChannel; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.dto.SearchResultDto; +import org.phoebus.channelfinder.web.v0.mapper.ChannelMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; @@ -22,13 +23,15 @@ public ChannelController(ChannelService channelService) { } @Override - public List query(MultiValueMap allRequestParams) { - return channelService.query(allRequestParams); + public List query(MultiValueMap allRequestParams) { + return channelService.query(allRequestParams).stream().map(ChannelMapper::toDto).toList(); } @Override - public SearchResult combinedQuery(MultiValueMap allRequestParams) { - return channelService.combinedQuery(allRequestParams); + public SearchResultDto combinedQuery(MultiValueMap allRequestParams) { + var result = channelService.combinedQuery(allRequestParams); + return new SearchResultDto( + result.channels().stream().map(ChannelMapper::toDto).toList(), result.count()); } @Override @@ -37,28 +40,28 @@ public long queryCount(MultiValueMap allRequestParams) { } @Override - public Channel read(String channelName) { - return channelService.read(channelName); + public ChannelDto read(String channelName) { + return ChannelMapper.toDto(channelService.read(channelName)); } @Override - public Channel create(String channelName, Channel channel) { - return channelService.create(channelName, channel); + public ChannelDto create(String channelName, ChannelDto channel) { + return ChannelMapper.toDto(channelService.create(channelName, ChannelMapper.toDomain(channel))); } @Override - public Iterable create(Iterable channels) { - return channelService.create(channels); + public Iterable create(Iterable channels) { + return ChannelMapper.toDtos(channelService.create(ChannelMapper.toDomains(channels))); } @Override - public Channel update(String channelName, Channel channel) { - return channelService.update(channelName, channel); + public ChannelDto update(String channelName, ChannelDto channel) { + return ChannelMapper.toDto(channelService.update(channelName, ChannelMapper.toDomain(channel))); } @Override - public Iterable update(Iterable channels) { - return channelService.update(channels); + public Iterable update(Iterable channels) { + return ChannelMapper.toDtos(channelService.update(ChannelMapper.toDomains(channels))); } @Override diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelProcessorController.java b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelProcessorController.java index a6ff5b5c..54da43a6 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelProcessorController.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelProcessorController.java @@ -1,10 +1,11 @@ package org.phoebus.channelfinder.web.v0.controller; import java.util.List; -import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.service.ChannelProcessorService; import org.phoebus.channelfinder.service.model.archiver.ChannelProcessorInfo; import org.phoebus.channelfinder.web.v0.api.IChannelProcessor; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.mapper.ChannelMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; @@ -42,8 +43,8 @@ public long processChannels(MultiValueMap allRequestParams) { } @Override - public void processChannels(List channels) { - channelProcessorService.sendToProcessors(channels); + public void processChannels(List channels) { + channelProcessorService.sendToProcessors(ChannelMapper.toDomains(channels)); } @Override diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelScrollController.java b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelScrollController.java index fe8c6b9d..fd2f0c67 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelScrollController.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/controller/ChannelScrollController.java @@ -1,8 +1,9 @@ package org.phoebus.channelfinder.web.v0.controller; -import org.phoebus.channelfinder.entity.Scroll; import org.phoebus.channelfinder.service.ChannelScrollService; import org.phoebus.channelfinder.web.v0.api.IChannelScroll; +import org.phoebus.channelfinder.web.v0.dto.ScrollDto; +import org.phoebus.channelfinder.web.v0.mapper.ChannelMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; @@ -20,12 +21,17 @@ public ChannelScrollController(ChannelScrollService channelScrollService) { } @Override - public Scroll query(MultiValueMap allRequestParams) { - return channelScrollService.search(null, allRequestParams); + public ScrollDto query(MultiValueMap allRequestParams) { + return toScrollDto(channelScrollService.search(null, allRequestParams)); } @Override - public Scroll query(String scrollId, MultiValueMap searchParameters) { - return channelScrollService.search(scrollId, searchParameters); + public ScrollDto query(String scrollId, MultiValueMap searchParameters) { + return toScrollDto(channelScrollService.search(scrollId, searchParameters)); + } + + private static ScrollDto toScrollDto(org.phoebus.channelfinder.entity.Scroll scroll) { + return new ScrollDto( + scroll.getId(), scroll.getChannels().stream().map(ChannelMapper::toDto).toList()); } } diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/controller/PropertyController.java b/src/main/java/org/phoebus/channelfinder/web/v0/controller/PropertyController.java index f794a640..8bb15cb9 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/controller/PropertyController.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/controller/PropertyController.java @@ -1,8 +1,9 @@ package org.phoebus.channelfinder.web.v0.controller; -import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.service.PropertyService; import org.phoebus.channelfinder.web.v0.api.IProperty; +import org.phoebus.channelfinder.web.v0.dto.PropertyDto; +import org.phoebus.channelfinder.web.v0.mapper.PropertyMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -19,38 +20,41 @@ public PropertyController(PropertyService propertyService) { } @Override - public Iterable list() { - return propertyService.list(); + public Iterable list() { + return PropertyMapper.toDtos(propertyService.list()); } @Override - public Property read(String propertyName, boolean withChannels) { - return propertyService.read(propertyName, withChannels); + public PropertyDto read(String propertyName, boolean withChannels) { + return PropertyMapper.toDto(propertyService.read(propertyName, withChannels)); } @Override - public Property create(String propertyName, Property property) { - return propertyService.create(propertyName, property); + public PropertyDto create(String propertyName, PropertyDto property) { + return PropertyMapper.toDto( + propertyService.create(propertyName, PropertyMapper.toDomain(property))); } @Override - public Iterable create(Iterable properties) { - return propertyService.create(properties); + public Iterable create(Iterable properties) { + return PropertyMapper.toDtos(propertyService.create(PropertyMapper.toDomains(properties))); } @Override - public Property addSingle(String propertyName, String channelName, Property property) { - return propertyService.addSingle(propertyName, channelName, property); + public PropertyDto addSingle(String propertyName, String channelName, PropertyDto property) { + return PropertyMapper.toDto( + propertyService.addSingle(propertyName, channelName, PropertyMapper.toDomain(property))); } @Override - public Property update(String propertyName, Property property) { - return propertyService.update(propertyName, property); + public PropertyDto update(String propertyName, PropertyDto property) { + return PropertyMapper.toDto( + propertyService.update(propertyName, PropertyMapper.toDomain(property))); } @Override - public Iterable update(Iterable properties) { - return propertyService.update(properties); + public Iterable update(Iterable properties) { + return PropertyMapper.toDtos(propertyService.update(PropertyMapper.toDomains(properties))); } @Override diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/controller/TagController.java b/src/main/java/org/phoebus/channelfinder/web/v0/controller/TagController.java index f9532c1d..b240dea6 100644 --- a/src/main/java/org/phoebus/channelfinder/web/v0/controller/TagController.java +++ b/src/main/java/org/phoebus/channelfinder/web/v0/controller/TagController.java @@ -1,8 +1,9 @@ package org.phoebus.channelfinder.web.v0.controller; -import org.phoebus.channelfinder.entity.Tag; import org.phoebus.channelfinder.service.TagService; import org.phoebus.channelfinder.web.v0.api.ITag; +import org.phoebus.channelfinder.web.v0.dto.TagDto; +import org.phoebus.channelfinder.web.v0.mapper.TagMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -19,38 +20,38 @@ public TagController(TagService tagService) { } @Override - public Iterable list() { - return tagService.list(); + public Iterable list() { + return TagMapper.toDtos(tagService.list()); } @Override - public Tag read(String tagName, boolean withChannels) { - return tagService.read(tagName, withChannels); + public TagDto read(String tagName, boolean withChannels) { + return TagMapper.toDto(tagService.read(tagName, withChannels)); } @Override - public Tag create(String tagName, Tag tag) { - return tagService.create(tagName, tag); + public TagDto create(String tagName, TagDto tag) { + return TagMapper.toDto(tagService.create(tagName, TagMapper.toDomain(tag))); } @Override - public Iterable create(Iterable tags) { - return tagService.create(tags); + public Iterable create(Iterable tags) { + return TagMapper.toDtos(tagService.create(TagMapper.toDomains(tags))); } @Override - public Tag addSingle(String tagName, String channelName) { - return tagService.addSingle(tagName, channelName); + public TagDto addSingle(String tagName, String channelName) { + return TagMapper.toDto(tagService.addSingle(tagName, channelName)); } @Override - public Tag update(String tagName, Tag tag) { - return tagService.update(tagName, tag); + public TagDto update(String tagName, TagDto tag) { + return TagMapper.toDto(tagService.update(tagName, TagMapper.toDomain(tag))); } @Override - public Iterable update(Iterable tags) { - return tagService.update(tags); + public Iterable update(Iterable tags) { + return TagMapper.toDtos(tagService.update(TagMapper.toDomains(tags))); } @Override diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/dto/ChannelDto.java b/src/main/java/org/phoebus/channelfinder/web/v0/dto/ChannelDto.java new file mode 100644 index 00000000..5971691d --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/dto/ChannelDto.java @@ -0,0 +1,17 @@ +package org.phoebus.channelfinder.web.v0.dto; + +import java.util.ArrayList; +import java.util.List; + +public record ChannelDto( + String name, String owner, List properties, List tags) { + + public ChannelDto { + properties = properties != null ? properties : new ArrayList<>(); + tags = tags != null ? tags : new ArrayList<>(); + } + + public ChannelDto(String name, String owner) { + this(name, owner, new ArrayList<>(), new ArrayList<>()); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/dto/PropertyDto.java b/src/main/java/org/phoebus/channelfinder/web/v0/dto/PropertyDto.java new file mode 100644 index 00000000..b5b5f46a --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/dto/PropertyDto.java @@ -0,0 +1,15 @@ +package org.phoebus.channelfinder.web.v0.dto; + +import java.util.ArrayList; +import java.util.List; + +public record PropertyDto(String name, String owner, String value, List channels) { + + public PropertyDto { + channels = channels != null ? channels : new ArrayList<>(); + } + + public PropertyDto(String name, String owner, String value) { + this(name, owner, value, new ArrayList<>()); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/dto/ScrollDto.java b/src/main/java/org/phoebus/channelfinder/web/v0/dto/ScrollDto.java new file mode 100644 index 00000000..ad9ed64c --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/dto/ScrollDto.java @@ -0,0 +1,5 @@ +package org.phoebus.channelfinder.web.v0.dto; + +import java.util.List; + +public record ScrollDto(String id, List channels) {} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/dto/SearchResultDto.java b/src/main/java/org/phoebus/channelfinder/web/v0/dto/SearchResultDto.java new file mode 100644 index 00000000..83c94701 --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/dto/SearchResultDto.java @@ -0,0 +1,5 @@ +package org.phoebus.channelfinder.web.v0.dto; + +import java.util.List; + +public record SearchResultDto(List channels, long count) {} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/dto/TagDto.java b/src/main/java/org/phoebus/channelfinder/web/v0/dto/TagDto.java new file mode 100644 index 00000000..096c23da --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/dto/TagDto.java @@ -0,0 +1,15 @@ +package org.phoebus.channelfinder.web.v0.dto; + +import java.util.ArrayList; +import java.util.List; + +public record TagDto(String name, String owner, List channels) { + + public TagDto { + channels = channels != null ? channels : new ArrayList<>(); + } + + public TagDto(String name, String owner) { + this(name, owner, new ArrayList<>()); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/mapper/ChannelMapper.java b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/ChannelMapper.java new file mode 100644 index 00000000..e1c1da98 --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/ChannelMapper.java @@ -0,0 +1,36 @@ +package org.phoebus.channelfinder.web.v0.mapper; + +import java.util.List; +import java.util.stream.StreamSupport; +import org.phoebus.channelfinder.entity.Channel; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; + +public final class ChannelMapper { + + private ChannelMapper() {} + + public static ChannelDto toDto(Channel channel) { + return new ChannelDto( + channel.getName(), + channel.getOwner(), + channel.getProperties().stream().map(PropertyMapper::toDto).toList(), + channel.getTags().stream().map(TagMapper::toDto).toList()); + } + + public static Channel toDomain(ChannelDto dto) { + Channel channel = new Channel(); + channel.setName(dto.name()); + channel.setOwner(dto.owner()); + channel.setProperties(dto.properties().stream().map(PropertyMapper::toDomain).toList()); + channel.setTags(dto.tags().stream().map(TagMapper::toDomain).toList()); + return channel; + } + + public static List toDtos(Iterable channels) { + return StreamSupport.stream(channels.spliterator(), false).map(ChannelMapper::toDto).toList(); + } + + public static List toDomains(Iterable dtos) { + return StreamSupport.stream(dtos.spliterator(), false).map(ChannelMapper::toDomain).toList(); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/mapper/PropertyMapper.java b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/PropertyMapper.java new file mode 100644 index 00000000..6a551096 --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/PropertyMapper.java @@ -0,0 +1,39 @@ +package org.phoebus.channelfinder.web.v0.mapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.StreamSupport; +import org.phoebus.channelfinder.entity.Property; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.dto.PropertyDto; + +public final class PropertyMapper { + + private PropertyMapper() {} + + public static PropertyDto toDto(Property property) { + List channels = + property.getChannels().isEmpty() + ? new ArrayList<>() + : property.getChannels().stream().map(ChannelMapper::toDto).toList(); + return new PropertyDto(property.getName(), property.getOwner(), property.getValue(), channels); + } + + public static Property toDomain(PropertyDto dto) { + Property property = new Property(dto.name(), dto.owner(), dto.value()); + if (!dto.channels().isEmpty()) { + property.setChannels(dto.channels().stream().map(ChannelMapper::toDomain).toList()); + } + return property; + } + + public static List toDtos(Iterable properties) { + return StreamSupport.stream(properties.spliterator(), false) + .map(PropertyMapper::toDto) + .toList(); + } + + public static List toDomains(Iterable dtos) { + return StreamSupport.stream(dtos.spliterator(), false).map(PropertyMapper::toDomain).toList(); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/web/v0/mapper/TagMapper.java b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/TagMapper.java new file mode 100644 index 00000000..ccba824d --- /dev/null +++ b/src/main/java/org/phoebus/channelfinder/web/v0/mapper/TagMapper.java @@ -0,0 +1,37 @@ +package org.phoebus.channelfinder.web.v0.mapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.StreamSupport; +import org.phoebus.channelfinder.entity.Tag; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.dto.TagDto; + +public final class TagMapper { + + private TagMapper() {} + + public static TagDto toDto(Tag tag) { + List channels = + tag.getChannels().isEmpty() + ? new ArrayList<>() + : tag.getChannels().stream().map(ChannelMapper::toDto).toList(); + return new TagDto(tag.getName(), tag.getOwner(), channels); + } + + public static Tag toDomain(TagDto dto) { + Tag tag = new Tag(dto.name(), dto.owner()); + if (!dto.channels().isEmpty()) { + tag.setChannels(dto.channels().stream().map(ChannelMapper::toDomain).toList()); + } + return tag; + } + + public static List toDtos(Iterable tags) { + return StreamSupport.stream(tags.spliterator(), false).map(TagMapper::toDto).toList(); + } + + public static List toDomains(Iterable dtos) { + return StreamSupport.stream(dtos.spliterator(), false).map(TagMapper::toDomain).toList(); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/ChannelControllerIT.java b/src/test/java/org/phoebus/channelfinder/ChannelControllerIT.java index 71d36c1e..538f67cb 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelControllerIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelControllerIT.java @@ -23,6 +23,7 @@ import org.phoebus.channelfinder.repository.TagRepository; import org.phoebus.channelfinder.web.v0.api.IChannel; import org.phoebus.channelfinder.web.v0.controller.ChannelController; +import org.phoebus.channelfinder.web.v0.mapper.ChannelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.security.test.context.support.WithMockUser; @@ -52,9 +53,9 @@ void readXmlChannel() { Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); cleanupTestChannels = Arrays.asList(testChannel0); - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + Channel createdChannel = apiCreate(testChannel0.getName(), testChannel0); - Channel readChannel = channelManager.read(createdChannel.getName()); + Channel readChannel = apiRead(createdChannel.getName()); // verify the channel was read as expected Assertions.assertEquals(createdChannel, readChannel, "Failed to read the channel"); } @@ -74,7 +75,7 @@ void createXmlChannel() { cleanupTestChannels = Arrays.asList(testChannel0); // Create a simple channel - Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + Channel createdChannel0 = apiCreate(testChannel0.getName(), testChannel0); // verify the channel was created as expected Assertions.assertEquals(testChannel0, createdChannel0, "Failed to create the channel"); @@ -84,7 +85,7 @@ void createXmlChannel() { // Update the test channel with a new owner testChannel0.setOwner("updateTestOwner"); - Channel updatedChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + Channel updatedChannel0 = apiCreate(testChannel0.getName(), testChannel0); // verify the channel was created as expected Assertions.assertEquals(testChannel0, updatedChannel0, "Failed to create the channel"); } @@ -96,8 +97,8 @@ void renameByCreateXmlChannel() { Channel testChannel1 = new Channel("testChannel1", "testOwner"); cleanupTestChannels = Arrays.asList(testChannel0, testChannel1); - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - createdChannel = channelManager.create(testChannel0.getName(), testChannel1); + Channel createdChannel = apiCreate(testChannel0.getName(), testChannel0); + createdChannel = apiCreate(testChannel0.getName(), testChannel1); // verify that the old channel "testChannel0" was replaced with the new "testChannel1" Assertions.assertEquals(testChannel1, createdChannel, "Failed to create the channel"); // verify that the old channel is no longer present @@ -112,7 +113,7 @@ void createXmlChannel2() { Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); cleanupTestChannels = Arrays.asList(testChannel0); - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + apiCreate(testChannel0.getName(), testChannel0); try { Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); Assertions.assertEquals( @@ -132,7 +133,7 @@ void createXmlChannel2() { // Update the test channel with a new owner testChannel0.setOwner("updateTestOwner"); - createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + apiCreate(testChannel0.getName(), testChannel0); try { Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); Assertions.assertEquals( @@ -156,9 +157,9 @@ void renameByCreateXmlChannel2() { cleanupTestChannels = Arrays.asList(testChannel0, testChannel1); // Create the testChannel0 - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + apiCreate(testChannel0.getName(), testChannel0); // update the testChannel0 with testChannel1 - createdChannel = channelManager.create(testChannel0.getName(), testChannel1); + apiCreate(testChannel0.getName(), testChannel1); // verify that the old channel "testChannel0" was replaced with the new "testChannel1" try { Channel foundChannel = channelRepository.findById(testChannel1.getName()).get(); @@ -181,7 +182,7 @@ void createXmlChannels() { List testChannels = Arrays.asList(testChannel0, testChannel1, testChannel2); cleanupTestChannels = testChannels; - Iterable createdChannels = channelManager.create(testChannels); + apiCreate(testChannels); List foundChannels = new ArrayList(); testChannels.forEach( chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); @@ -200,14 +201,16 @@ void createXmlChannelsWithOverride() { cleanupTestChannels = testChannels; // Create a set of original channels to be overriden - channelManager.create(testChannels); + apiCreate(testChannels); // Now update the test channels testChannel0.setOwner("testOwner-updated"); testChannel1.setTags(Collections.emptyList()); testChannel1.setProperties(Collections.emptyList()); List updatedTestChannels = Arrays.asList(testChannel0, testChannel1); - channelManager.create(updatedTestChannels); + apiCreate(updatedTestChannels); + // Owner does not change for existing channels on create-override + testChannel0.setOwner("testOwner"); List foundChannels = new ArrayList(); testChannels.forEach( chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); @@ -229,7 +232,7 @@ void updateXmlChannel() { // Update on a non-existing channel should result in the creation of that channel // 1. Test a simple channel - Channel returnedChannel = channelManager.update(testChannel0.getName(), testChannel0); + Channel returnedChannel = apiUpdate(testChannel0.getName(), testChannel0); Assertions.assertEquals( testChannel0, returnedChannel, "Failed to update channel " + testChannel0); Assertions.assertEquals( @@ -237,7 +240,7 @@ void updateXmlChannel() { channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); // 2. Test a channel with tags and props - returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); + returnedChannel = apiUpdate(testChannel1.getName(), testChannel1); Assertions.assertEquals( testChannel1, returnedChannel, "Failed to update channel " + testChannel1); Assertions.assertEquals( @@ -247,7 +250,7 @@ void updateXmlChannel() { // Update the channel owner testChannel0.setOwner("newTestOwner"); - returnedChannel = channelManager.update(testChannel0.getName(), testChannel0); + returnedChannel = apiUpdate(testChannel0.getName(), testChannel0); Assertions.assertEquals( testChannel0, returnedChannel, "Failed to update channel " + testChannel0); Assertions.assertEquals( @@ -255,7 +258,7 @@ void updateXmlChannel() { channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); testChannel1.setOwner("newTestOwner"); - returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); + returnedChannel = apiUpdate(testChannel1.getName(), testChannel1); Assertions.assertEquals( testChannel1, returnedChannel, "Failed to update channel " + testChannel1); Assertions.assertEquals( @@ -275,11 +278,11 @@ void renameByUpdateXmlChannel() { cleanupTestChannels = Arrays.asList(testChannel0, testChannel1, testChannel2, testChannel3); // Create the testChannels - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - Channel createdChannelWithItems = channelManager.create(testChannel2.getName(), testChannel2); + apiCreate(testChannel0.getName(), testChannel0); + apiCreate(testChannel2.getName(), testChannel2); // update the testChannels - Channel renamedChannel = channelManager.update(testChannel0.getName(), testChannel1); - Channel renamedChannelWithItems = channelManager.update(testChannel2.getName(), testChannel3); + apiUpdate(testChannel0.getName(), testChannel1); + apiUpdate(testChannel2.getName(), testChannel3); // verify that the old channels were replaced by the new ones try { @@ -318,7 +321,7 @@ void updateXmlChannelItems() { cleanupTestChannels = Arrays.asList(testChannel0); // Create the testChannel - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + apiCreate(testChannel0.getName(), testChannel0); // set up the new testChannel testProperties.get(1).setValue("newValue"); @@ -330,7 +333,7 @@ void updateXmlChannelItems() { Arrays.asList(testTags.get(1), testTags.get(2))); // update the testChannel - Channel updatedChannel = channelManager.update(testChannel0.getName(), testChannel0); + apiUpdate(testChannel0.getName(), testChannel0); Channel expectedChannel = new Channel("testChannel0", "testOwner", testProperties, testTags); Channel foundChannel = channelRepository.findById("testChannel0").get(); @@ -370,7 +373,7 @@ void updateMultipleXmlChannels() { cleanupTestChannels = testChannels; // Update on non-existing channels should result in the creation of those channels - Iterable returnedChannels = channelManager.update(testChannels); + apiUpdate(testChannels); // 1. Test a simple channel Assertions.assertEquals( testChannel0, @@ -382,10 +385,12 @@ void updateMultipleXmlChannels() { channelRepository.findById(testChannel1.getName()).get(), "Failed to update channel " + testChannel1); - // Update the channel owner + // Owner does not change for existing channels on batch update testChannel0.setOwner("newTestOwner"); testChannel1.setOwner("newTestOwner"); - returnedChannels = channelManager.update(testChannels); + apiUpdate(testChannels); + testChannel0.setOwner("testOwner"); + testChannel1.setOwner("testOwner"); Assertions.assertEquals( testChannel0, channelRepository.findById(testChannel0.getName()).get(), @@ -416,7 +421,7 @@ void updateMultipleXmlChannelsWithItems() { cleanupTestChannels = testChannels; // Create the testChannel - Iterable createdChannels = channelManager.create(testChannels); + apiCreate(testChannels); // set up the new testChannel testProperties.forEach(prop -> prop.setValue("newValue")); @@ -435,7 +440,7 @@ void updateMultipleXmlChannelsWithItems() { testChannels = Arrays.asList(testChannel0, testChannel1); // update the testChannel - Iterable updatedChannels = channelManager.update(testChannels); + apiUpdate(testChannels); // set up the expected testChannels testChannel0 = @@ -494,7 +499,7 @@ void deleteXmlChannel() { Channel testChannel0 = new Channel("testChannel0", "testOwner"); cleanupTestChannels = Arrays.asList(testChannel0); - channelManager.create(testChannel0.getName(), testChannel0); + apiCreate(testChannel0.getName(), testChannel0); channelManager.remove(testChannel0.getName()); // verify the channel was deleted as expected Assertions.assertFalse( @@ -562,4 +567,24 @@ void setupAll() { void tearDown() throws IOException { ElasticConfigIT.teardown(esService); } + + private Channel apiCreate(String name, Channel channel) { + return ChannelMapper.toDomain(channelManager.create(name, ChannelMapper.toDto(channel))); + } + + private Iterable apiCreate(Iterable channels) { + return ChannelMapper.toDomains(channelManager.create(ChannelMapper.toDtos(channels))); + } + + private Channel apiRead(String name) { + return ChannelMapper.toDomain(channelManager.read(name)); + } + + private Channel apiUpdate(String name, Channel channel) { + return ChannelMapper.toDomain(channelManager.update(name, ChannelMapper.toDto(channel))); + } + + private Iterable apiUpdate(Iterable channels) { + return ChannelMapper.toDomains(channelManager.update(ChannelMapper.toDtos(channels))); + } } diff --git a/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerIT.java b/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerIT.java index 5d682c82..77058597 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerIT.java @@ -9,13 +9,13 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import org.phoebus.channelfinder.configuration.ElasticConfig; import org.phoebus.channelfinder.configuration.PopulateDBConfiguration; -import org.phoebus.channelfinder.entity.Channel; -import org.phoebus.channelfinder.entity.Scroll; import org.phoebus.channelfinder.repository.ChannelRepository; import org.phoebus.channelfinder.repository.PropertyRepository; import org.phoebus.channelfinder.repository.TagRepository; import org.phoebus.channelfinder.web.v0.api.IChannelScroll; import org.phoebus.channelfinder.web.v0.controller.ChannelScrollController; +import org.phoebus.channelfinder.web.v0.dto.ChannelDto; +import org.phoebus.channelfinder.web.v0.dto.ScrollDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.test.context.ContextConfiguration; @@ -83,33 +83,32 @@ void searchNameTest() throws InterruptedException { MultiValueMap searchParameters = new LinkedMultiValueMap(); // Search for a single unique channel searchParameters.add("~name", channelNames.get(0)); - Scroll scrollResult = channelScroll.query(searchParameters); - List result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + ScrollDto scrollResult = channelScroll.query(searchParameters); + List result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } - Assertions.assertTrue( - result.size() == 1 && result.get(0).getName().equals(channelNames.get(0))); + Assertions.assertTrue(result.size() == 1 && result.get(0).name().equals(channelNames.get(0))); // Search for all channels via wildcards searchParameters.clear(); searchParameters.add("~name", "BR:C001-BI:2{BLA}Pos:?-RB"); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertSame(2, result.size(), "Expected 2 but got " + result.size()); searchParameters.clear(); searchParameters.add("~name", "BR:C001-BI:?{BLA}Pos:*"); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertSame(4, result.size(), "Expected 4 but got " + result.size()); @@ -117,10 +116,10 @@ void searchNameTest() throws InterruptedException { searchParameters.clear(); searchParameters.add("~name", "SR*"); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertEquals(1000, result.size(), "Expected 1000 but got " + result.size()); @@ -128,20 +127,20 @@ void searchNameTest() throws InterruptedException { searchParameters.clear(); searchParameters.add("~name", "SR*|BR*"); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); searchParameters.clear(); searchParameters.add("~name", "SR*,BR*"); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); @@ -155,10 +154,10 @@ void searchNameTest() throws InterruptedException { searchParameters.add("~tag", "group" + id + "_" + val_bucket.get(index)); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertEquals( val_bucket.get(index), @@ -181,10 +180,10 @@ void searchNameTest() throws InterruptedException { searchParameters.add("group" + id, String.valueOf(val_bucket.get(index))); scrollResult = channelScroll.query(searchParameters); - result = new ArrayList<>(scrollResult.getChannels()); - while (scrollResult.getChannels().size() == 100) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); + result = new ArrayList<>(scrollResult.channels()); + while (scrollResult.channels().size() == 100) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); + result.addAll(scrollResult.channels()); } Assertions.assertEquals( val_bucket.get(index), diff --git a/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerSearchIT.java b/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerSearchIT.java index 1fd6970e..3ab5da05 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerSearchIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelScrollControllerSearchIT.java @@ -11,11 +11,11 @@ import org.junit.jupiter.api.TestInstance; import org.phoebus.channelfinder.configuration.ElasticConfig; import org.phoebus.channelfinder.configuration.PopulateDBConfiguration; -import org.phoebus.channelfinder.entity.Scroll; import org.phoebus.channelfinder.repository.PropertyRepository; import org.phoebus.channelfinder.repository.TagRepository; import org.phoebus.channelfinder.web.v0.api.IChannelScroll; import org.phoebus.channelfinder.web.v0.controller.ChannelScrollController; +import org.phoebus.channelfinder.web.v0.dto.ScrollDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.test.context.ContextConfiguration; @@ -71,7 +71,7 @@ void searchNameTest() { searchParameters.add("~size", "100"); long start = System.currentTimeMillis(); - Scroll scrollResult = channelScroll.query(searchParameters); + ScrollDto scrollResult = channelScroll.query(searchParameters); logger.log( Level.INFO, "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); @@ -83,28 +83,28 @@ void searchNameTest() { "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); - while (scrollResult.getChannels().size() == 100) { - logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + while (scrollResult.channels().size() == 100) { + logger.log(Level.INFO, "Retireval id: " + scrollResult.id()); + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); logger.log( Level.INFO, "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); } logger.log(Level.INFO, "total result = " + totalResult); @@ -125,28 +125,28 @@ void searchNameTest() { "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); - while (scrollResult.getChannels().size() == 1000) { - logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + while (scrollResult.channels().size() == 1000) { + logger.log(Level.INFO, "Retireval id: " + scrollResult.id()); + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); logger.log( Level.INFO, "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); } logger.log(Level.INFO, "total result = " + totalResult); @@ -168,27 +168,27 @@ void searchNameTest() { "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); - while (scrollResult.getChannels().size() == 10000) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + while (scrollResult.channels().size() == 10000) { + scrollResult = channelScroll.query(scrollResult.id(), searchParameters); logger.log( Level.FINE, "Retrieved channels " + totalResult + " to " - + (totalResult + scrollResult.getChannels().size()) + + (totalResult + scrollResult.channels().size()) + " in : " + (System.currentTimeMillis() - start) + "ms"); avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); + totalResult += scrollResult.channels().size(); start = System.currentTimeMillis(); } logger.log(Level.INFO, "total result = " + totalResult); diff --git a/src/test/java/org/phoebus/channelfinder/PropertyControllerIT.java b/src/test/java/org/phoebus/channelfinder/PropertyControllerIT.java index 49f7020a..381f6e97 100644 --- a/src/test/java/org/phoebus/channelfinder/PropertyControllerIT.java +++ b/src/test/java/org/phoebus/channelfinder/PropertyControllerIT.java @@ -24,6 +24,7 @@ import org.phoebus.channelfinder.repository.PropertyRepository; import org.phoebus.channelfinder.web.v0.api.IProperty; import org.phoebus.channelfinder.web.v0.controller.PropertyController; +import org.phoebus.channelfinder.web.v0.mapper.PropertyMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.security.test.context.support.WithMockUser; @@ -99,8 +100,8 @@ void listXmlProperties() { new ArrayList()))); List testProperties = Arrays.asList(testProperty0, testProperty1); - Iterable createdProperties = propertyManager.create(testProperties); - Iterable propertyList = propertyManager.list(); + Iterable createdProperties = apiCreate(testProperties); + Iterable propertyList = apiList(); for (Property property : createdProperties) { property.setChannels(new ArrayList()); } @@ -122,24 +123,24 @@ void readXmlProperty() { new Property(testProperty1.getName(), testProperty1.getOwner(), "value")), new ArrayList()))); - Property createdProperty0 = propertyManager.create(testProperty0.getName(), testProperty0); - Property createdProperty1 = propertyManager.create(testProperty1.getName(), testProperty1); + Property createdProperty0 = apiCreate(testProperty0.getName(), testProperty0); + Property createdProperty1 = apiCreate(testProperty1.getName(), testProperty1); // verify the created properties are read as expected // retrieve the testProperty0 without channels - Property retrievedProperty = propertyManager.read(createdProperty0.getName(), false); + Property retrievedProperty = apiRead(createdProperty0.getName(), false); Assertions.assertEquals(createdProperty0, retrievedProperty, "Failed to read the property"); // retrieve the testProperty0 with channels - retrievedProperty = propertyManager.read(createdProperty0.getName(), true); + retrievedProperty = apiRead(createdProperty0.getName(), true); Assertions.assertEquals( createdProperty0, retrievedProperty, "Failed to read the property w/ channels"); - retrievedProperty = propertyManager.read(createdProperty1.getName(), false); + retrievedProperty = apiRead(createdProperty1.getName(), false); // verify the property was read as expected testProperty1.setChannels(new ArrayList()); Assertions.assertEquals(testProperty1, retrievedProperty, "Failed to read the property"); - retrievedProperty = propertyManager.read(createdProperty1.getName(), true); + retrievedProperty = apiRead(createdProperty1.getName(), true); // verify the property was read as expected Assertions.assertEquals( createdProperty1, retrievedProperty, "Failed to read the property w/ channels"); @@ -167,7 +168,7 @@ void createXmlProperty() { Property testProperty0 = new Property("testProperty0", "testOwner"); // Create a simple property - Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); + Property createdProperty = apiCreate(testProperty0.getName(), testProperty0); Assertions.assertEquals(testProperty0, createdProperty, "Failed to create the property"); // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); @@ -176,7 +177,7 @@ void createXmlProperty() { // Update the test property with a new owner Property updatedTestProperty0 = new Property("testProperty0", "updateTestOwner"); - createdProperty = propertyManager.create(testProperty0.getName(), updatedTestProperty0); + createdProperty = apiCreate(testProperty0.getName(), updatedTestProperty0); Assertions.assertEquals(updatedTestProperty0, createdProperty, "Failed to create the property"); } @@ -186,8 +187,8 @@ void renameByCreateXmlProperty() { Property testProperty0 = new Property("testProperty0", "testOwner"); Property testProperty1 = new Property("testProperty1", "testOwner"); - Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); - createdProperty = propertyManager.create(testProperty0.getName(), testProperty1); + Property createdProperty = apiCreate(testProperty0.getName(), testProperty0); + createdProperty = apiCreate(testProperty0.getName(), testProperty1); // verify that the old property "testProperty0" was replaced with the new "testProperty1" Assertions.assertEquals(testProperty1, createdProperty, "Failed to create the property"); // verify that the old property is no longer present @@ -213,7 +214,7 @@ void createXmlProperty2() { new ArrayList()))); Property createdProperty = - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); try { Property foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); @@ -236,8 +237,7 @@ void createXmlProperty2() { Property updatedTestProperty0WithChannels = new Property("testProperty0WithChannels", "updateTestOwner"); createdProperty = - propertyManager.create( - testProperty0WithChannels.getName(), updatedTestProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), updatedTestProperty0WithChannels); try { Property foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); @@ -283,10 +283,9 @@ void renameByCreateXmlProperty2() { // Create the testProperty0WithChannels Property createdProperty = - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // update the testProperty0WithChannels with testProperty1WithChannels - createdProperty = - propertyManager.create(testProperty0WithChannels.getName(), testProperty1WithChannels); + createdProperty = apiCreate(testProperty0WithChannels.getName(), testProperty1WithChannels); try { Property foundProperty = propertyRepository.findById(testProperty1WithChannels.getName(), true).get(); @@ -353,7 +352,7 @@ void createXmlProperties() { testProperty1WithChannels, testProperty2WithChannels); - Iterable createdProperties = propertyManager.create(testProperties); + apiCreate(testProperties); List foundProperties = new ArrayList(); testProperties.forEach( prop -> foundProperties.add(propertyRepository.findById(prop.getName(), true).get())); @@ -403,7 +402,7 @@ void createXmlPropertiesWithOverride() { List testProperties = Arrays.asList(testProperty0, testProperty0WithChannels); // Create a set of original properties to be overriden - propertyManager.create(testProperties); + apiCreate(testProperties); // Now update the test properties testProperty0.setOwner("testOwner-updated"); testProperty0WithChannels.setOwner("testOwner-updated"); @@ -420,11 +419,12 @@ void createXmlPropertiesWithOverride() { new ArrayList()))); List updatedTestProperties = Arrays.asList(testProperty0, testProperty0WithChannels); - propertyManager.create(updatedTestProperties); + apiCreate(updatedTestProperties); - // set owner back to original since it shouldn't change + // set owner back to original since it shouldn't change; also normalize channel property owners testProperty0.setOwner("testOwner"); testProperty0WithChannels.setOwner("testOwner"); + testProperty0WithChannels.getChannels().get(0).getProperties().get(0).setOwner("testOwner"); List foundProperties = new ArrayList(); testProperties.forEach( @@ -456,7 +456,7 @@ void addSingleXmlProperty() { propertyRepository.index(testProperty0); testProperty0.setValue("value"); - propertyManager.addSingle(testProperty0.getName(), "testChannel0", testProperty0); + apiAddSingle(testProperty0.getName(), "testChannel0", testProperty0); Assertions.assertTrue( channelRepository.findById("testChannel0").get().getProperties().stream() .anyMatch( @@ -489,7 +489,7 @@ void updateXmlProperty() { // Update on a non-existing property should result in the creation of that property // 1. Test a simple property - Property returnedProperty = propertyManager.update(testProperty0.getName(), testProperty0); + Property returnedProperty = apiUpdate(testProperty0.getName(), testProperty0); Assertions.assertEquals( testProperty0, returnedProperty, "Failed to update property " + testProperty0); Assertions.assertEquals( @@ -497,8 +497,7 @@ void updateXmlProperty() { propertyRepository.findById(testProperty0.getName()).get(), "Failed to update property " + testProperty0); // 2. Test a property with channels - returnedProperty = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + returnedProperty = apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedProperty, @@ -510,7 +509,7 @@ void updateXmlProperty() { // Update the property owner testProperty0.setOwner("newTestOwner"); - returnedProperty = propertyManager.update(testProperty0.getName(), testProperty0); + returnedProperty = apiUpdate(testProperty0.getName(), testProperty0); Assertions.assertEquals( testProperty0, returnedProperty, "Failed to update property " + testProperty0); Assertions.assertEquals( @@ -529,8 +528,7 @@ void updateXmlProperty() { testProperty0WithChannels.getOwner(), "value")), new ArrayList()))); - returnedProperty = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + returnedProperty = apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedProperty, @@ -594,9 +592,9 @@ void updateXmlPropertyOnChan() { "newValueX")), EMPTY_LIST))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // change name and owner on existing channel, add to new channel - propertyManager.update(testProperty0WithChannels.getName(), testProperty1WithChannels); + apiUpdate(testProperty0WithChannels.getName(), testProperty1WithChannels); Property expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner"); expectedProperty.setChannels( @@ -713,13 +711,11 @@ void renameByUpdateXmlProperty() { new ArrayList()))); // Create the original properties - Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); - Property createdPropertyWithChannels = - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0.getName(), testProperty0); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // update the properties with new names, 0 -> 1 - Property updatedProperty = propertyManager.create(testProperty0.getName(), testProperty1); - Property updatedPropertyWithChannels = - propertyManager.create(testProperty0WithChannels.getName(), testProperty1WithChannels); + apiCreate(testProperty0.getName(), testProperty1); + apiCreate(testProperty0WithChannels.getName(), testProperty1WithChannels); // verify that the old property "testProperty0" was replaced with the new "testProperty1" try { @@ -758,7 +754,7 @@ void renameByUpdateXmlProperty() { void updatePropertyTest1() { // A test property with only name and owner Property testProperty0 = new Property("testProperty0", "testOwner"); - propertyManager.create(testProperty0.getName(), testProperty0); + apiCreate(testProperty0.getName(), testProperty0); // Updating a property with no channels, the new channels should be added to the property // Add testChannel0 to testProperty0 which has no channels testProperty0.setChannels( @@ -769,7 +765,7 @@ void updatePropertyTest1() { Arrays.asList( new Property(testProperty0.getName(), testProperty0.getOwner(), "value")), new ArrayList()))); - Property returnedTag = propertyManager.update(testProperty0.getName(), testProperty0); + Property returnedTag = apiUpdate(testProperty0.getName(), testProperty0); Assertions.assertEquals( testProperty0, returnedTag, "Failed to update property " + testProperty0); Assertions.assertEquals( @@ -797,7 +793,7 @@ void updatePropertyTest2() { testProperty0WithChannels.getOwner(), "value")), new ArrayList()))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // Updating a property with existing channels, the new channels should be added without // affecting existing channels // testProperty0WithChannels already has testChannel0, the update operation should append the @@ -814,7 +810,7 @@ void updatePropertyTest2() { "value")), new ArrayList()))); Property returnedTag = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedTag, @@ -865,7 +861,7 @@ void updatePropertyTest3() { testProperty0WithChannels.getOwner(), "value")), new ArrayList()))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // testProperty0WithChannels already has testChannel0, the update request (which repeats the // testChannel0) // should append the testChannel1 while leaving the existing channel unaffected. @@ -890,7 +886,7 @@ void updatePropertyTest3() { "value")), new ArrayList()))); Property returnedTag = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedTag, @@ -930,13 +926,13 @@ void updatePropertyTest4() { testProperty0WithChannels.getOwner(), "value")), new ArrayList()))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // Updating a property with existing channels, the new channels should be added without // affecting existing channels // testProperty0WithChannels already has testChannel0 & testChannel1, the update request should // be a NOP. Property returnedTag = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedTag, @@ -976,7 +972,7 @@ void updatePropertyTest5() { testProperty0WithChannels.getOwner(), "value")), new ArrayList()))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); // Updating a property with existing channels, the new channels should be added without // affecting existing channels // testProperty0WithChannels already has testChannel0 & testChannel1, the update request should @@ -993,7 +989,7 @@ void updatePropertyTest5() { "value")), new ArrayList()))); Property returnedTag = - propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiUpdate(testProperty0WithChannels.getName(), testProperty0WithChannels); Assertions.assertEquals( testProperty0WithChannels, returnedTag, @@ -1072,8 +1068,8 @@ void updatePropertyWithChannelsTest() { "property1channel1")), new ArrayList()))); - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - propertyManager.create(testProperty1WithChannels.getName(), testProperty1WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty1WithChannels.getName(), testProperty1WithChannels); Property newValueProperty = new Property( @@ -1091,7 +1087,7 @@ void updatePropertyWithChannelsTest() { newValueProperty.getOwner(), "newValueProperty")), new ArrayList()))); - propertyManager.update(newValueProperty.getName(), newValueProperty); + apiUpdate(newValueProperty.getName(), newValueProperty); List expected0Properties = List.of( @@ -1150,7 +1146,7 @@ void updateMultipleProperties() { "value")), new ArrayList()))); - propertyManager.update(Arrays.asList(testProperty0, testProperty0WithChannels)); + apiUpdate(Arrays.asList(testProperty0, testProperty0WithChannels)); // Query ChannelFinder and verify updated channels and properties Property foundProperty = propertyRepository.findById(testProperty0.getName(), true).get(); Assertions.assertEquals( @@ -1212,7 +1208,7 @@ void updateMultipleXmlPropertiesOnChan() { "valueX")), new ArrayList()))); - propertyManager.create(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); + apiCreate(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); // change owners and add channels and change values testProperty0WithChannels.setOwner("updateTestOwner"); testProperty0WithChannels.setChannels( @@ -1258,7 +1254,7 @@ void updateMultipleXmlPropertiesOnChan() { EMPTY_LIST))); // update both properties - propertyManager.update(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); + apiUpdate(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); // create expected properties // verify that the properties were updated @@ -1339,7 +1335,7 @@ void deleteXmlProperty() { EMPTY_LIST))); List testProperties = Arrays.asList(testProperty0, testProperty0WithChannels); - Iterable createdProperties = propertyManager.create(testProperties); + apiCreate(testProperties); propertyManager.remove(testProperty0.getName()); // verify the property was deleted as expected @@ -1376,7 +1372,7 @@ void deleteXmlPropertyFromChannel() { new ArrayList()))); Property createdProperty = - propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + apiCreate(testProperty0WithChannels.getName(), testProperty0WithChannels); propertyManager.removeSingle(testProperty0WithChannels.getName(), testChannel0.getName()); // verify the property was only removed from the single test channel @@ -1395,4 +1391,33 @@ void deleteXmlPropertyFromChannel() { }), "Failed to delete the property from channel"); } + + private Property apiCreate(String name, Property property) { + return PropertyMapper.toDomain(propertyManager.create(name, PropertyMapper.toDto(property))); + } + + private Iterable apiCreate(Iterable properties) { + return PropertyMapper.toDomains(propertyManager.create(PropertyMapper.toDtos(properties))); + } + + private Property apiRead(String name, boolean withChannels) { + return PropertyMapper.toDomain(propertyManager.read(name, withChannels)); + } + + private Iterable apiList() { + return PropertyMapper.toDomains(propertyManager.list()); + } + + private Property apiUpdate(String name, Property property) { + return PropertyMapper.toDomain(propertyManager.update(name, PropertyMapper.toDto(property))); + } + + private void apiUpdate(Iterable properties) { + propertyManager.update(PropertyMapper.toDtos(properties)); + } + + private Property apiAddSingle(String propertyName, String channelName, Property property) { + return PropertyMapper.toDomain( + propertyManager.addSingle(propertyName, channelName, PropertyMapper.toDto(property))); + } } diff --git a/src/test/java/org/phoebus/channelfinder/TagControllerIT.java b/src/test/java/org/phoebus/channelfinder/TagControllerIT.java index 3d2f833c..67c25167 100644 --- a/src/test/java/org/phoebus/channelfinder/TagControllerIT.java +++ b/src/test/java/org/phoebus/channelfinder/TagControllerIT.java @@ -24,6 +24,7 @@ import org.phoebus.channelfinder.repository.TagRepository; import org.phoebus.channelfinder.web.v0.api.ITag; import org.phoebus.channelfinder.web.v0.controller.TagController; +import org.phoebus.channelfinder.web.v0.mapper.TagMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.security.test.context.support.WithMockUser; @@ -61,9 +62,9 @@ void listXmlTags() { testTag1.setChannels(testChannels()); List testTags = Arrays.asList(testTag0, testTag1); - Iterable createdTags = tagManager.create(testTags); + Iterable createdTags = apiCreate(testTags); - Iterable tagList = tagManager.list(); + Iterable tagList = apiList(); for (Tag tag : createdTags) { tag.setChannels(new ArrayList<>()); } @@ -78,23 +79,23 @@ void readXmlTag() { Tag testTag1 = new Tag("testTag1", "testOwner"); testTag1.setChannels(testChannels()); - Tag createdTag0 = tagManager.create(testTag0.getName(), testTag0); - Tag createdTag1 = tagManager.create(testTag1.getName(), testTag1); + Tag createdTag0 = apiCreate(testTag0.getName(), testTag0); + Tag createdTag1 = apiCreate(testTag1.getName(), testTag1); // verify the created tags are read as expected // Retrieve the testTag0 without channels - Tag retrievedTag = tagManager.read(createdTag0.getName(), false); + Tag retrievedTag = apiRead(createdTag0.getName(), false); Assertions.assertEquals(createdTag0, retrievedTag, "Failed to read the tag"); // Retrieve the testTag0 with channels - retrievedTag = tagManager.read(createdTag0.getName(), true); + retrievedTag = apiRead(createdTag0.getName(), true); Assertions.assertEquals(createdTag0, retrievedTag, "Failed to read the tag w/ channels"); // Retrieve the testTag1 without channels - retrievedTag = tagManager.read(createdTag1.getName(), false); + retrievedTag = apiRead(createdTag1.getName(), false); testTag1.setChannels(new ArrayList<>()); Assertions.assertEquals(testTag1, retrievedTag, "Failed to read the tag"); // Retrieve the testTag1 with channels - retrievedTag = tagManager.read(createdTag1.getName(), true); + retrievedTag = apiRead(createdTag1.getName(), true); Assertions.assertEquals(createdTag1, retrievedTag, "Failed to read the tag w/ channels"); } @@ -118,12 +119,12 @@ void createXmlTag() { Tag testTag0 = new Tag("testTag0", "testOwner"); // Create a simple tag - Tag createdTag = tagManager.create(testTag0.getName(), testTag0); + Tag createdTag = apiCreate(testTag0.getName(), testTag0); Assertions.assertEquals(testTag0, createdTag, "Failed to create the tag"); // Update the test tag with a new owner Tag updatedTestTag0 = new Tag("testTag0", "updateTestOwner"); - createdTag = tagManager.create(testTag0.getName(), copy(updatedTestTag0)); + createdTag = apiCreate(testTag0.getName(), copy(updatedTestTag0)); Assertions.assertEquals(updatedTestTag0, createdTag, "Failed to create the tag"); } @@ -133,8 +134,8 @@ void renameByCreateXmlTag() { Tag testTag0 = new Tag("testTag0", "testOwner"); Tag testTag1 = new Tag("testTag1", "testOwner"); - tagManager.create(testTag0.getName(), testTag0); - Tag createdTag = tagManager.create(testTag0.getName(), testTag1); + apiCreate(testTag0.getName(), testTag0); + Tag createdTag = apiCreate(testTag0.getName(), testTag1); // verify that the old tag "testTag0" was replaced with the new "testTag1" Assertions.assertEquals(testTag1, createdTag, "Failed to create the tag"); // verify that the old tag is no longer present @@ -148,7 +149,7 @@ void createXmlTag2() { Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); testTag0WithChannels.setChannels(testChannels()); - tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); + apiCreate(testTag0WithChannels.getName(), testTag0WithChannels); try { Tag foundTag = tagRepository.findById(testTag0WithChannels.getName(), true).get(); Tag expectedTag = new Tag("testTag0WithChannels", "testOwner"); @@ -178,7 +179,7 @@ void createXmlTag2() { Tag updatedTestTag0WithChannels = new Tag("testTag0WithChannels", "updateTestOwner"); - tagManager.create(testTag0WithChannels.getName(), copy(updatedTestTag0WithChannels)); + apiCreate(testTag0WithChannels.getName(), copy(updatedTestTag0WithChannels)); try { Tag foundTag = tagRepository.findById(updatedTestTag0WithChannels.getName(), true).get(); // verify the tag was created as expected @@ -199,9 +200,9 @@ void renameByCreateXmlTag2() { testTag1WithChannels.setChannels(testChannels()); // Create the testTag0WithChannels - tagManager.create(testTag0WithChannels.getName(), copy(testTag0WithChannels)); + apiCreate(testTag0WithChannels.getName(), copy(testTag0WithChannels)); // update the testTag0WithChannels with testTag1WithChannels - tagManager.create(testTag0WithChannels.getName(), copy(testTag1WithChannels)); + apiCreate(testTag0WithChannels.getName(), copy(testTag1WithChannels)); try { Tag foundTag = tagRepository.findById(testTag1WithChannels.getName(), true).get(); Assertions.assertFalse( @@ -245,7 +246,7 @@ void createXmlTags() { testTag1WithChannels, testTag2WithChannels); - tagManager.create(copy(testTags)); + apiCreate(copy(testTags)); List foundTags = new ArrayList(); testTags.forEach(tag -> foundTags.add(tagRepository.findById(tag.getName(), true).get())); Assertions.assertTrue(foundTags.contains(testTag0), "Failed to create the tags testTag0 "); @@ -281,15 +282,15 @@ void createXmlTagsWithOverride() { List testTags = Arrays.asList(testTag0, testTag0WithChannels); // Create a set of original tags to be overriden - tagManager.create("testTag0", copy(testTag0)); - tagManager.create("testTag0WithChannels", copy(testTag0WithChannels)); + apiCreate("testTag0", copy(testTag0)); + apiCreate("testTag0WithChannels", copy(testTag0WithChannels)); // Now update the test tags testTag0.setOwner("testOwner-updated"); testTag0WithChannels.setOwner("testOwner-updated"); testTag0WithChannels.setChannels(Arrays.asList(testChannel1)); List updatedTestTags = Arrays.asList(testTag0, testTag0WithChannels); - Iterable createdTags = tagManager.create(copy(updatedTestTags)); + apiCreate(copy(updatedTestTags)); // set owner back to original since it shouldn't change testTag0.setOwner("testOwner"); @@ -321,7 +322,7 @@ void addSingleXmlTag() { Tag testTag0 = new Tag("testTag0", "testOwner"); tagRepository.index(testTag0); - tagManager.addSingle(testTag0.getName(), "testChannel0"); + apiAddSingle(testTag0.getName(), "testChannel0"); Assertions.assertTrue( channelRepository.findById("testChannel0").get().getTags().stream() .anyMatch(t -> t.getName().equals(testTag0.getName())), @@ -339,14 +340,14 @@ void updateXmlTag() { // Update on a non-existing tag should result in the creation of that tag // 1. Test a simple tag - Tag returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + Tag returnedTag = apiUpdate(testTag0.getName(), copy(testTag0)); Assertions.assertEquals(testTag0, returnedTag, "Failed to update tag " + testTag0); Assertions.assertEquals( testTag0, tagRepository.findById(testTag0.getName()).get(), "Failed to update tag " + testTag0); // 2. Test a tag with channels - returnedTag = tagManager.update(testTag0WithChannels.getName(), copy(testTag0WithChannels)); + returnedTag = apiUpdate(testTag0WithChannels.getName(), copy(testTag0WithChannels)); Assertions.assertTrue( returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) && returnedTag.getChannels().size() == 1, @@ -358,14 +359,14 @@ void updateXmlTag() { // Update the tag owner testTag0.setOwner("newTestOwner"); - returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + returnedTag = apiUpdate(testTag0.getName(), copy(testTag0)); Assertions.assertEquals(testTag0, returnedTag, "Failed to update tag " + testTag0); Assertions.assertEquals( testTag0, tagRepository.findById(testTag0.getName()).get(), "Failed to update tag " + testTag0); testTag0WithChannels.setOwner("newTestOwner"); - returnedTag = tagManager.update(testTag0WithChannels.getName(), copy(testTag0WithChannels)); + returnedTag = apiUpdate(testTag0WithChannels.getName(), copy(testTag0WithChannels)); Assertions.assertTrue( returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) && returnedTag.getChannels().size() == 1, @@ -392,9 +393,9 @@ void updateXmlTagOnChan() { testTag1WithChannels.setChannels( Arrays.asList(testChannels().get(1), new Channel("testChannelX", "testOwner"))); - tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); + apiCreate(testTag0WithChannels.getName(), testTag0WithChannels); // change name and owner on existing channel, add to new channel - tagManager.update(testTag0WithChannels.getName(), testTag1WithChannels); + apiUpdate(testTag0WithChannels.getName(), testTag1WithChannels); Tag expectedTag = new Tag("testTag1WithChannels", "updateTestOwner"); expectedTag.setChannels( @@ -457,13 +458,11 @@ void renameByUpdateXmlTag() { testTag1WithChannels.setChannels(testChannels()); // Create the original tags - Tag createdTag = tagManager.create(testTag0.getName(), testTag0); - Tag createdTagWithChannels = - tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); + apiCreate(testTag0.getName(), testTag0); + apiCreate(testTag0WithChannels.getName(), testTag0WithChannels); // update the tags with new names, 0 -> 1 - Tag updatedTag = tagManager.update(testTag0.getName(), testTag1); - Tag updatedTagWithChannels = - tagManager.update(testTag0WithChannels.getName(), testTag1WithChannels); + apiUpdate(testTag0.getName(), testTag1); + apiUpdate(testTag0WithChannels.getName(), testTag1WithChannels); // verify that the old tag "testTag0" was replaced with the new "testTag1" Optional foundTag = tagRepository.findById(testTag1.getName()); @@ -493,11 +492,11 @@ void renameByUpdateXmlTag() { void updateTagTest1() { // A test tag with only name and owner Tag testTag0 = new Tag("testTag0", "testOwner"); - tagManager.create(testTag0.getName(), testTag0); + apiCreate(testTag0.getName(), testTag0); // Updating a tag with no channels, the new channels should be added to the tag // Add testChannel0 to testTag0 which has no channels testTag0.setChannels(Arrays.asList(testChannels().get(0))); - Tag returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + Tag returnedTag = apiUpdate(testTag0.getName(), copy(testTag0)); Assertions.assertEquals( returnedTag, tagRepository.findById(testTag0.getName(), true).get(), @@ -513,14 +512,14 @@ void updateTagTest2() { // A test tag with testChannel0 Tag testTag0 = new Tag("testTag0", "testOwner"); testTag0.setChannels(Arrays.asList(testChannels().get(0))); - Tag createdTag = tagManager.create(testTag0.getName(), testTag0); + Tag createdTag = apiCreate(testTag0.getName(), testTag0); Assertions.assertSame(1, createdTag.getChannels().size(), "Failed to update tag " + testTag0); // Updating a tag with existing channels, the new channels should be added without affecting // existing channels // testTag0 already has testChannel0, the update operation should append the testChannel1 while // leaving the existing channel unaffected. testTag0.setChannels(Arrays.asList(testChannels().get(1))); - Tag returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + apiUpdate(testTag0.getName(), copy(testTag0)); // Query ChannelFinder and verify updated channels and tags Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); @@ -537,12 +536,12 @@ void updateTagTest3() { Tag testTag0 = new Tag("testTag0", "testOwner"); testTag0.setChannels(Arrays.asList(testChannels().get(0))); - tagManager.create(testTag0.getName(), testTag0); + apiCreate(testTag0.getName(), testTag0); // testTag0 already has testChannel0, the update request (which repeats the testChannel0) should // append // the testChannel1 while leaving the existing channel unaffected. testTag0.setChannels(testChannels()); - tagManager.update(testTag0.getName(), copy(testTag0)); + apiUpdate(testTag0.getName(), copy(testTag0)); // Query ChannelFinder and verify updated channels and tags Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); @@ -578,12 +577,12 @@ void updateTagTest4() { // existing channels // testTag0 already has testChannel0 & testChannel1, the update request should be a NOP. testTag0.setChannels(testChannels()); - Tag returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + Tag returnedTag = apiUpdate(testTag0.getName(), copy(testTag0)); Assertions.assertSame(2, returnedTag.getChannels().size(), "Failed to update tag " + testTag0); // Query ChannelFinder and verify updated channels and tags Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); - Tag expectedTag = tagManager.create(testTag0.getName(), testTag0); + Tag expectedTag = apiCreate(testTag0.getName(), testTag0); expectedTag.setChannels( Arrays.asList( new Channel( @@ -608,13 +607,13 @@ void updateTagTest5() { // A test tag with testChannel0,testChannel1 Tag testTag0 = new Tag("testTag0", "testOwner"); testTag0.setChannels(testChannels()); - Tag expectedTag = tagManager.create(testTag0.getName(), testTag0); + Tag expectedTag = apiCreate(testTag0.getName(), testTag0); // Updating a tag with existing channels, the new channels should be added without affecting // existing channels // testTag0 already has testChannel0 & testChannel1, the update operation should be a NOP. testTag0.setChannels(Arrays.asList(testChannels().get(0))); - Tag returnedTag = tagManager.update(testTag0.getName(), copy(testTag0)); + Tag returnedTag = apiUpdate(testTag0.getName(), copy(testTag0)); Assertions.assertSame(2, returnedTag.getChannels().size(), "Failed to update tag " + testTag0); // Query ChannelFinder and verify updated channels and tags Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); @@ -645,7 +644,7 @@ void updateMultipleTags() { testTag0WithChannels.setChannels(testChannels()); Iterable returnedTag = - tagManager.update(Arrays.asList(copy(testTag0), copy(testTag0WithChannels))); + apiUpdate(Arrays.asList(copy(testTag0), copy(testTag0WithChannels))); // Query ChannelFinder and verify updated channels and tags Optional foundTag = tagRepository.findById(testTag0.getName(), true); Assertions.assertTrue( @@ -670,7 +669,7 @@ void updateMultipleXmlTagsOnChan() { Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(1), testChannelX)); - tagManager.create(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); + apiCreate(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); // change owners and add channels testTag0WithChannels.setOwner("updateTestOwner"); testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(1), testChannelX)); @@ -678,7 +677,7 @@ void updateMultipleXmlTagsOnChan() { testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(0), testChannelX)); // update both tags - tagManager.update(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); + apiUpdate(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); // verify that the tags were updated Tag foundTag0 = tagRepository.findById(testTag0WithChannels.getName(), true).get(); @@ -729,7 +728,7 @@ void deleteXmlTag() { testTag1.setChannels(testChannels()); List testTags = Arrays.asList(testTag0, testTag1); - Iterable createdTags = tagManager.create(testTags); + apiCreate(testTags); tagManager.remove(testTag0.getName()); // verify the tag was deleted as expected @@ -754,7 +753,7 @@ void deleteXmlTagFromChannel() { Tag testTag1 = new Tag("testTag1", "testOwner"); testTag1.setChannels(testChannels()); - Tag createdTag = tagManager.create(testTag1.getName(), testTag1); + apiCreate(testTag1.getName(), testTag1); tagManager.removeSingle(testTag1.getName(), testChannels().get(0).getName()); // verify the tag was only removed from the single test channel @@ -825,4 +824,32 @@ private static List copy(List tags) { tags.forEach(tag -> copy.add(copy(tag))); return copy; } + + private Tag apiCreate(String name, Tag tag) { + return TagMapper.toDomain(tagManager.create(name, TagMapper.toDto(tag))); + } + + private Iterable apiCreate(Iterable tags) { + return TagMapper.toDomains(tagManager.create(TagMapper.toDtos(tags))); + } + + private Tag apiRead(String name, boolean withChannels) { + return TagMapper.toDomain(tagManager.read(name, withChannels)); + } + + private Iterable apiList() { + return TagMapper.toDomains(tagManager.list()); + } + + private Tag apiUpdate(String name, Tag tag) { + return TagMapper.toDomain(tagManager.update(name, TagMapper.toDto(tag))); + } + + private Iterable apiUpdate(Iterable tags) { + return TagMapper.toDomains(tagManager.update(TagMapper.toDtos(tags))); + } + + private Tag apiAddSingle(String tagName, String channelName) { + return TagMapper.toDomain(tagManager.addSingle(tagName, channelName)); + } } diff --git a/src/test/java/org/phoebus/channelfinder/epics/EpicsRPCRequestIT.java b/src/test/java/org/phoebus/channelfinder/epics/EpicsRPCRequestIT.java index 4cea3488..d79b49d3 100644 --- a/src/test/java/org/phoebus/channelfinder/epics/EpicsRPCRequestIT.java +++ b/src/test/java/org/phoebus/channelfinder/epics/EpicsRPCRequestIT.java @@ -23,6 +23,9 @@ import org.phoebus.channelfinder.web.v0.api.IChannel; import org.phoebus.channelfinder.web.v0.api.IProperty; import org.phoebus.channelfinder.web.v0.api.ITag; +import org.phoebus.channelfinder.web.v0.mapper.ChannelMapper; +import org.phoebus.channelfinder.web.v0.mapper.PropertyMapper; +import org.phoebus.channelfinder.web.v0.mapper.TagMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.security.test.context.support.WithMockUser; @@ -77,16 +80,17 @@ void testRPCService() throws ExecutionException, InterruptedException, TimeoutEx Property testProperty0 = new Property("testProperty0", "testOwner", "testPropertyValue0"); Property testProperty1 = new Property("testProperty1", "testOwner", "testPropertyValue1"); List properties = List.of(testProperty0, testProperty1); - propertyManager.create(properties); + propertyManager.create(PropertyMapper.toDtos(properties)); testChannel0.setProperties(properties); // Create tag Tag tag = new Tag("testTag", "testOwner"); - tagManager.create(List.of(tag)); + tagManager.create(TagMapper.toDtos(List.of(tag))); testChannel0.setTags(List.of(tag)); // Create a simple channel - Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + ChannelMapper.toDomain( + channelManager.create(testChannel0.getName(), ChannelMapper.toDto(testChannel0))); Channel expectedChannel = new Channel("testChannel0", "testOwner");