diff --git a/pom.xml b/pom.xml index f50468dd..4336b1ba 100644 --- a/pom.xml +++ b/pom.xml @@ -229,6 +229,25 @@ maven-surefire-plugin 3.1.2 + + com.spotify.fmt + fmt-maven-plugin + 2.23 + + .*\.java + false + + + + + formatter + + format + check + + + + org.apache.maven.plugins diff --git a/src/main/java/org/phoebus/channelfinder/Application.java b/src/main/java/org/phoebus/channelfinder/Application.java index 73d2f2d3..ca17a6df 100644 --- a/src/main/java/org/phoebus/channelfinder/Application.java +++ b/src/main/java/org/phoebus/channelfinder/Application.java @@ -10,6 +10,8 @@ */ package org.phoebus.channelfinder; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.servers.Server; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -19,9 +21,6 @@ import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; - -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.servers.Server; import org.phoebus.channelfinder.example.PopulateService; import org.phoebus.channelfinder.processors.ChannelProcessor; import org.springframework.beans.factory.annotation.Autowired; @@ -38,95 +37,95 @@ import org.springframework.util.FileCopyUtils; @EnableAutoConfiguration -@ComponentScan(basePackages="org.phoebus.channelfinder") +@ComponentScan(basePackages = "org.phoebus.channelfinder") @EnableScheduling -@OpenAPIDefinition( - servers = { - @Server(url = "/") - } -) +@OpenAPIDefinition(servers = {@Server(url = "/")}) @SpringBootApplication public class Application implements ApplicationRunner { - static final Logger logger = Logger.getLogger(Application.class.getName()); + static final Logger logger = Logger.getLogger(Application.class.getName()); - public static void main(String[] args){ - // Set the java truststore used by channelfinder - configureTruststore(); - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + // Set the java truststore used by channelfinder + configureTruststore(); + SpringApplication.run(Application.class, args); + } - /** - * Set the default ssl trust store - */ - private static void configureTruststore() { - if (System.getProperty("javax.net.ssl.trustStore") == null) { - logger.log(Level.INFO, "using default javax.net.ssl.trustStore"); - try (InputStream in = Application.class.getResourceAsStream("/keystore/cacerts")) { - // read input - File tempFile= File.createTempFile("cf-", "-truststore"); - FileOutputStream out = new FileOutputStream(tempFile); - FileCopyUtils.copy(in, out); - tempFile.deleteOnExit(); - System.setProperty("javax.net.ssl.trustStore", tempFile.getAbsolutePath()); - } catch (IOException e) { - logger.log(Level.SEVERE, "failed to configure channelfinder truststore", e); - } - } - if (System.getProperty("javax.net.ssl.trustStorePassword") == null) { - logger.log(Level.INFO, "using default javax.net.ssl.trustStorePassword"); - System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); - } + /** Set the default ssl trust store */ + private static void configureTruststore() { + if (System.getProperty("javax.net.ssl.trustStore") == null) { + logger.log(Level.INFO, "using default javax.net.ssl.trustStore"); + try (InputStream in = Application.class.getResourceAsStream("/keystore/cacerts")) { + // read input + File tempFile = File.createTempFile("cf-", "-truststore"); + FileOutputStream out = new FileOutputStream(tempFile); + FileCopyUtils.copy(in, out); + tempFile.deleteOnExit(); + System.setProperty("javax.net.ssl.trustStore", tempFile.getAbsolutePath()); + } catch (IOException e) { + logger.log(Level.SEVERE, "failed to configure channelfinder truststore", e); + } + } + if (System.getProperty("javax.net.ssl.trustStorePassword") == null) { + logger.log(Level.INFO, "using default javax.net.ssl.trustStorePassword"); + System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); } + } - @Autowired - PopulateService service; + @Autowired PopulateService service; - public void run(ApplicationArguments args) throws Exception { - if(args.containsOption("demo-data")) { - int numberOfCells = args.getOptionValues("demo-data").stream().mapToInt(Integer::valueOf).max().orElse(1); - logger.log(Level.INFO, "Populating the channelfinder service with demo data"); - service.createDB(numberOfCells); - } - if(args.containsOption("cleanup")) { - int numberOfCells = args.getOptionValues("cleanup").stream().mapToInt(Integer::valueOf).max().orElse(1); - // This is kind of a hack, the create Db is being called to reset the channels and then deleting them - logger.log(Level.INFO, "Populating the channelfinder service with demo data first, then deleting them"); - service.createDB(numberOfCells); - logger.log(Level.INFO, "Cleaning up the populated demo data"); - service.cleanupDB(); - } + public void run(ApplicationArguments args) throws Exception { + if (args.containsOption("demo-data")) { + int numberOfCells = + args.getOptionValues("demo-data").stream().mapToInt(Integer::valueOf).max().orElse(1); + logger.log(Level.INFO, "Populating the channelfinder service with demo data"); + service.createDB(numberOfCells); } - - /** - * List of {@link ChannelProcessor} implementations called when new channels are created or existing channels are updated - * - * @return A list of {@link ChannelProcessor}s, if any have been registered over SPI. - */ - @Bean - public List channelProcessors() { - List processors = new ArrayList<>(); - ServiceLoader loader = ServiceLoader.load(ChannelProcessor.class); - loader.stream().forEach(p -> { - ChannelProcessor notifier = p.get(); - processors.add(notifier); - }); - return processors; + if (args.containsOption("cleanup")) { + int numberOfCells = + args.getOptionValues("cleanup").stream().mapToInt(Integer::valueOf).max().orElse(1); + // This is kind of a hack, the create Db is being called to reset the channels and then + // deleting them + logger.log( + Level.INFO, + "Populating the channelfinder service with demo data first, then deleting them"); + service.createDB(numberOfCells); + logger.log(Level.INFO, "Cleaning up the populated demo data"); + service.cleanupDB(); } + } - /** - * {@link TaskExecutor} used when calling {@link ChannelProcessor}s. - * - * @return A {@link TaskExecutor} - */ - @Bean - public TaskExecutor taskExecutor() { - ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); - taskExecutor.setCorePoolSize(3); - taskExecutor.setMaxPoolSize(10); - taskExecutor.setQueueCapacity(25); + /** + * List of {@link ChannelProcessor} implementations called when new channels are created or + * existing channels are updated + * + * @return A list of {@link ChannelProcessor}s, if any have been registered over SPI. + */ + @Bean + public List channelProcessors() { + List processors = new ArrayList<>(); + ServiceLoader loader = ServiceLoader.load(ChannelProcessor.class); + loader.stream() + .forEach( + p -> { + ChannelProcessor notifier = p.get(); + processors.add(notifier); + }); + return processors; + } - return taskExecutor; - } + /** + * {@link TaskExecutor} used when calling {@link ChannelProcessor}s. + * + * @return A {@link TaskExecutor} + */ + @Bean + public TaskExecutor taskExecutor() { + ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + taskExecutor.setCorePoolSize(3); + taskExecutor.setMaxPoolSize(10); + taskExecutor.setQueueCapacity(25); + return taskExecutor; + } } diff --git a/src/main/java/org/phoebus/channelfinder/AuthorizationService.java b/src/main/java/org/phoebus/channelfinder/AuthorizationService.java index 3067a579..822fd43e 100644 --- a/src/main/java/org/phoebus/channelfinder/AuthorizationService.java +++ b/src/main/java/org/phoebus/channelfinder/AuthorizationService.java @@ -6,7 +6,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; - import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.entity.Tag; @@ -18,102 +17,101 @@ @Service public class AuthorizationService { - public static List admin_groups; - public static List channel_groups; - public static List property_groups; - public static List tag_groups; + public static List admin_groups; + public static List channel_groups; + public static List property_groups; + public static List tag_groups; - @Value("${admin-groups:cf-admins}") - void initializeAdminRoles(String groups) { - AuthorizationService.admin_groups = Arrays.asList(groups.split(",")).stream().map(g -> - "ROLE_" + g.trim().toUpperCase() - ).collect(Collectors.toList()); - } - @Value("${channel-groups:cf-channels}") - void initializeChannelModRoles(String groups) { - AuthorizationService.channel_groups = Arrays.asList(groups.split(",")).stream().map(g -> - "ROLE_" + g.trim().toUpperCase() - ).collect(Collectors.toList()); - } - @Value("${property-groups:cf-properties}") - void initializePropertyRoles(String groups) { - AuthorizationService.property_groups = Arrays.asList(groups.split(",")).stream().map(g -> - "ROLE_" + g.trim().toUpperCase() - ).collect(Collectors.toList()); - } - @Value("${tag-groups:cf-tags}") - void initializeTagRoles(String groups) { - AuthorizationService.tag_groups = Arrays.asList(groups.split(",")).stream().map(g -> - "ROLE_" + g.trim().toUpperCase() - ).collect(Collectors.toList()); - } + @Value("${admin-groups:cf-admins}") + void initializeAdminRoles(String groups) { + AuthorizationService.admin_groups = + Arrays.asList(groups.split(",")).stream() + .map(g -> "ROLE_" + g.trim().toUpperCase()) + .collect(Collectors.toList()); + } - public enum ROLES { - CF_ADMIN(admin_groups), - CF_CHANNEL(channel_groups), - CF_PROPERTY(property_groups), - CF_TAG(tag_groups); + @Value("${channel-groups:cf-channels}") + void initializeChannelModRoles(String groups) { + AuthorizationService.channel_groups = + Arrays.asList(groups.split(",")).stream() + .map(g -> "ROLE_" + g.trim().toUpperCase()) + .collect(Collectors.toList()); + } - private final List groups; + @Value("${property-groups:cf-properties}") + void initializePropertyRoles(String groups) { + AuthorizationService.property_groups = + Arrays.asList(groups.split(",")).stream() + .map(g -> "ROLE_" + g.trim().toUpperCase()) + .collect(Collectors.toList()); + } - private ROLES(List groups) { - this.groups = groups; - } - } + @Value("${tag-groups:cf-tags}") + void initializeTagRoles(String groups) { + AuthorizationService.tag_groups = + Arrays.asList(groups.split(",")).stream() + .map(g -> "ROLE_" + g.trim().toUpperCase()) + .collect(Collectors.toList()); + } - public boolean isAuthorizedOwner(Authentication authentication, Tag data) { - ArrayList auth = new ArrayList<>(); - Collection auths = authentication.getAuthorities(); - for(GrantedAuthority a: auths) - auth.add(a.getAuthority()); - - if(!Collections.disjoint(auth,ROLES.CF_ADMIN.groups)) - return true; - if(authentication.getName().equals(data.getOwner()) || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) - return true; - return false; - } + public enum ROLES { + CF_ADMIN(admin_groups), + CF_CHANNEL(channel_groups), + CF_PROPERTY(property_groups), + CF_TAG(tag_groups); - public boolean isAuthorizedOwner(Authentication authentication, Property data) { - ArrayList auth = new ArrayList<>(); - Collection auths = authentication.getAuthorities(); - for(GrantedAuthority a: auths) - auth.add(a.getAuthority()); - - if(!Collections.disjoint(auth,ROLES.CF_ADMIN.groups)) - return true; - if(authentication.getName().equals(data.getOwner()) || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) - return true; - return false; - } + private final List groups; - public boolean isAuthorizedOwner(Authentication authentication, Channel data) { - ArrayList auth = new ArrayList<>(); - Collection auths = authentication.getAuthorities(); - for(GrantedAuthority a: auths) - auth.add(a.getAuthority()); - - if(!Collections.disjoint(auth,ROLES.CF_ADMIN.groups)) - return true; - if(authentication.getName().equals(data.getOwner()) || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) - return true; - return false; + private ROLES(List groups) { + this.groups = groups; } + } - public boolean isAuthorizedRole(Authentication authentication, ROLES expectedRole) { - ArrayList auth = new ArrayList<>(); - Collection auths = authentication.getAuthorities(); - for(GrantedAuthority a: auths) - auth.add(a.getAuthority()); - - if(!Collections.disjoint(auth,ROLES.CF_ADMIN.groups)) - return true; - else if(!Collections.disjoint(auth,ROLES.CF_CHANNEL.groups) && expectedRole != ROLES.CF_ADMIN) - return true; - else if(!Collections.disjoint(auth,ROLES.CF_PROPERTY.groups) && (expectedRole == ROLES.CF_PROPERTY || expectedRole == ROLES.CF_TAG)) - return true; - else if(!Collections.disjoint(auth,ROLES.CF_TAG.groups) && expectedRole == ROLES.CF_TAG) - return true; - return false; - } + public boolean isAuthorizedOwner(Authentication authentication, Tag data) { + ArrayList auth = new ArrayList<>(); + Collection auths = authentication.getAuthorities(); + for (GrantedAuthority a : auths) auth.add(a.getAuthority()); + + if (!Collections.disjoint(auth, ROLES.CF_ADMIN.groups)) return true; + if (authentication.getName().equals(data.getOwner()) + || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) return true; + return false; + } + + public boolean isAuthorizedOwner(Authentication authentication, Property data) { + ArrayList auth = new ArrayList<>(); + Collection auths = authentication.getAuthorities(); + for (GrantedAuthority a : auths) auth.add(a.getAuthority()); + + if (!Collections.disjoint(auth, ROLES.CF_ADMIN.groups)) return true; + if (authentication.getName().equals(data.getOwner()) + || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) return true; + return false; + } + + public boolean isAuthorizedOwner(Authentication authentication, Channel data) { + ArrayList auth = new ArrayList<>(); + Collection auths = authentication.getAuthorities(); + for (GrantedAuthority a : auths) auth.add(a.getAuthority()); + + if (!Collections.disjoint(auth, ROLES.CF_ADMIN.groups)) return true; + if (authentication.getName().equals(data.getOwner()) + || auth.contains("ROLE_" + data.getOwner().trim().toUpperCase())) return true; + return false; + } + + public boolean isAuthorizedRole(Authentication authentication, ROLES expectedRole) { + ArrayList auth = new ArrayList<>(); + Collection auths = authentication.getAuthorities(); + for (GrantedAuthority a : auths) auth.add(a.getAuthority()); + + if (!Collections.disjoint(auth, ROLES.CF_ADMIN.groups)) return true; + else if (!Collections.disjoint(auth, ROLES.CF_CHANNEL.groups) && expectedRole != ROLES.CF_ADMIN) + return true; + else if (!Collections.disjoint(auth, ROLES.CF_PROPERTY.groups) + && (expectedRole == ROLES.CF_PROPERTY || expectedRole == ROLES.CF_TAG)) return true; + else if (!Collections.disjoint(auth, ROLES.CF_TAG.groups) && expectedRole == ROLES.CF_TAG) + return true; + return false; + } } diff --git a/src/main/java/org/phoebus/channelfinder/CFResourceDescriptors.java b/src/main/java/org/phoebus/channelfinder/CFResourceDescriptors.java index 6bc535b3..34037fdf 100644 --- a/src/main/java/org/phoebus/channelfinder/CFResourceDescriptors.java +++ b/src/main/java/org/phoebus/channelfinder/CFResourceDescriptors.java @@ -2,19 +2,19 @@ public class CFResourceDescriptors { - public static final String CF_SERVICE = "ChannelFinder"; - public static final String CF_SERVICE_INFO = CF_SERVICE; - public static final String TAG_RESOURCE_URI = CF_SERVICE + "/resources/tags"; - public static final String PROPERTY_RESOURCE_URI = CF_SERVICE + "/resources/properties"; - public static final String CHANNEL_RESOURCE_URI = CF_SERVICE + "/resources/channels"; - public static final String SCROLL_RESOURCE_URI = CF_SERVICE + "/resources/scroll"; - public static final String CHANNEL_PROCESSOR_RESOURCE_URI = CF_SERVICE + "/resources/processors"; + public static final String CF_SERVICE = "ChannelFinder"; + public static final String CF_SERVICE_INFO = CF_SERVICE; + public static final String TAG_RESOURCE_URI = CF_SERVICE + "/resources/tags"; + public static final String PROPERTY_RESOURCE_URI = CF_SERVICE + "/resources/properties"; + public static final String CHANNEL_RESOURCE_URI = CF_SERVICE + "/resources/channels"; + public static final String SCROLL_RESOURCE_URI = CF_SERVICE + "/resources/scroll"; + public static final String CHANNEL_PROCESSOR_RESOURCE_URI = CF_SERVICE + "/resources/processors"; - public static final String SEARCH_PARAM_DESCRIPTION = - "Search parameters. Examples:\n" + - "- ~name: Filter by channel name (e.g., ~name=SR*)\n" + - "- ~tag: Filter by tag name, use ! to negate (e.g., ~tag=active)\n" + - "- ~size: Number of results (e.g., ~size=100)\n" + - "- ~from: Starting index (e.g., ~from=0)\n" + - "Use |,; as value separators"; + public static final String SEARCH_PARAM_DESCRIPTION = + "Search parameters. Examples:\n" + + "- ~name: Filter by channel name (e.g., ~name=SR*)\n" + + "- ~tag: Filter by tag name, use ! to negate (e.g., ~tag=active)\n" + + "- ~size: Number of results (e.g., ~size=100)\n" + + "- ~from: Starting index (e.g., ~from=0)\n" + + "Use |,; as value separators"; } diff --git a/src/main/java/org/phoebus/channelfinder/ChannelManager.java b/src/main/java/org/phoebus/channelfinder/ChannelManager.java index 5fa411c5..061d3130 100644 --- a/src/main/java/org/phoebus/channelfinder/ChannelManager.java +++ b/src/main/java/org/phoebus/channelfinder/ChannelManager.java @@ -1,14 +1,26 @@ package org.phoebus.channelfinder; +import static org.phoebus.channelfinder.CFResourceDescriptors.CHANNEL_RESOURCE_URI; +import static org.phoebus.channelfinder.CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION; + import com.google.common.collect.FluentIterable; import com.google.common.collect.Lists; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; +import java.text.MessageFormat; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import javax.servlet.ServletContext; import org.phoebus.channelfinder.AuthorizationService.ROLES; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; @@ -32,624 +44,706 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; -import javax.servlet.ServletContext; -import java.text.MessageFormat; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import static org.phoebus.channelfinder.CFResourceDescriptors.CHANNEL_RESOURCE_URI; -import static org.phoebus.channelfinder.CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION; - @CrossOrigin @RestController @RequestMapping(CHANNEL_RESOURCE_URI) @EnableAutoConfiguration public class ChannelManager { - private static final Logger channelManagerAudit = Logger.getLogger(ChannelManager.class.getName() + ".audit"); - private static final Logger logger = Logger.getLogger(ChannelManager.class.getName()); - - @Autowired - private ServletContext servletContext; - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - AuthorizationService authorizationService; - - @Autowired - ChannelProcessorService channelProcessorService; - - @Operation( - summary = "Query channels", - description = "Query a collection of Channel instances based on tags, property values, and channel names.", - operationId = "queryChannels", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "List of channels", - content = @Content( - array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to find all channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping - public List query( - @Parameter(description = SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap allRequestParams) { - return channelRepository.search(allRequestParams).channels(); + private static final Logger channelManagerAudit = + Logger.getLogger(ChannelManager.class.getName() + ".audit"); + private static final Logger logger = Logger.getLogger(ChannelManager.class.getName()); + + @Autowired private ServletContext servletContext; + + @Autowired TagRepository tagRepository; + + @Autowired PropertyRepository propertyRepository; + + @Autowired ChannelRepository channelRepository; + + @Autowired AuthorizationService authorizationService; + + @Autowired ChannelProcessorService channelProcessorService; + + @Operation( + summary = "Query channels", + description = + "Query a collection of Channel instances based on tags, property values, and channel names.", + operationId = "queryChannels", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "List of channels", + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to find all channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping + public List query( + @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap allRequestParams) { + return channelRepository.search(allRequestParams).channels(); + } + + @Operation( + summary = "Combined query for channels", + description = + "Query for a collection of Channel instances and get a count and the first 10k hits.", + operationId = "combinedQueryChannels", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The number of matches for the query, and the first 10k channels", + content = + @Content( + array = @ArraySchema(schema = @Schema(implementation = SearchResult.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request - response size exceeded", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to find all channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/combined") + public SearchResult combinedQuery( + @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap allRequestParams) { + return channelRepository.search(allRequestParams); + } + + @Operation( + summary = "Count channels matching query", + description = "Get the number of channels matching the given query parameters.", + operationId = "countChannels", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The number of channels matching the query", + content = @Content(schema = @Schema(implementation = Long.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to count the result for channel-query", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/count") + public long queryCount( + @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap allRequestParams) { + return channelRepository.count(allRequestParams); + } + + @Operation( + summary = "Get channel by name", + description = "Retrieve a Channel instance by its name.", + operationId = "getChannelByName", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Channel with the specified name", + content = @Content(schema = @Schema(implementation = Channel.class))), + @ApiResponse( + responseCode = "404", + description = "Channel not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/{channelName}") + public Channel read(@PathVariable("channelName") String channelName) { + channelManagerAudit.log( + Level.INFO, () -> MessageFormat.format(TextUtil.FIND_CHANNEL, channelName)); + + Optional foundChannel = channelRepository.findById(channelName); + if (foundChannel.isPresent()) return foundChannel.get(); + else { + String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); } - - @Operation( - summary = "Combined query for channels", - description = "Query for a collection of Channel instances and get a count and the first 10k hits.", - operationId = "combinedQueryChannels", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The number of matches for the query, and the first 10k channels", - content = @Content( - array = @ArraySchema(schema = @Schema(implementation = SearchResult.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request - response size exceeded", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to find all channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/combined") - public SearchResult combinedQuery( - @Parameter(description = SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap allRequestParams) { - return channelRepository.search(allRequestParams); - } - - @Operation( - summary = "Count channels matching query", - description = "Get the number of channels matching the given query parameters.", - operationId = "countChannels", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The number of channels matching the query", - content = @Content(schema = @Schema(implementation = Long.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to count the result for channel-query", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/count") - public long queryCount( - @Parameter(description = SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap allRequestParams) { - return channelRepository.count(allRequestParams); - } - - @Operation( - summary = "Get channel by name", - description = "Retrieve a Channel instance by its name.", - operationId = "getChannelByName", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Channel with the specified name", - content = @Content(schema = @Schema(implementation = Channel.class))), - @ApiResponse( - responseCode = "404", - description = "Channel not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/{channelName}") - public Channel read(@PathVariable("channelName") String channelName) { - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.FIND_CHANNEL, channelName)); - - Optional foundChannel = channelRepository.findById(channelName); - if (foundChannel.isPresent()) - return foundChannel.get(); - else { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } - - @Operation( - summary = "Create or replace a channel", - description = "Create or replace a channel instance identified by the payload.", - operationId = "createOrReplaceChannel", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The created/replaced channel", - content = @Content(schema = @Schema(implementation = Channel.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Channel, Tag, or property not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create channel", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/{channelName}") - public Channel create(@PathVariable("channelName") String channelName, @RequestBody Channel channel) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); - // Validate request parameters - validateChannelRequest(channel); - - // check if authorized owner - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), channel), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channel, HttpStatus.UNAUTHORIZED); - Optional existingChannel = channelRepository.findById(channelName); - boolean present = existingChannel.isPresent(); - if(present) { - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, existingChannel.get(), HttpStatus.UNAUTHORIZED); - // delete existing channel - channelRepository.deleteById(channelName); - } - - // reset owners of attached tags/props back to existing owners - channel.getProperties().forEach(prop -> prop.setOwner(propertyRepository.findById(prop.getName()).get().getOwner())); - channel.getTags().forEach(tag -> tag.setOwner(tagRepository.findById(tag.getName()).get().getOwner())); - - Channel createdChannel = channelRepository.index(channel); - // process the results - channelProcessorService.sendToProcessors(List.of(createdChannel)); - // create new channel - return createdChannel; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } + } + + @Operation( + summary = "Create or replace a channel", + description = "Create or replace a channel instance identified by the payload.", + operationId = "createOrReplaceChannel", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The created/replaced channel", + content = @Content(schema = @Schema(implementation = Channel.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Channel, Tag, or property not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create channel", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/{channelName}") + public Channel create( + @PathVariable("channelName") String channelName, @RequestBody Channel channel) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { + channelManagerAudit.log( + Level.INFO, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); + // Validate request parameters + validateChannelRequest(channel); + + // check if authorized owner + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), channel), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + channel, + HttpStatus.UNAUTHORIZED); + Optional existingChannel = channelRepository.findById(channelName); + boolean present = existingChannel.isPresent(); + if (present) { + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + existingChannel.get(), + HttpStatus.UNAUTHORIZED); + // delete existing channel + channelRepository.deleteById(channelName); + } + + // reset owners of attached tags/props back to existing owners + channel + .getProperties() + .forEach( + prop -> prop.setOwner(propertyRepository.findById(prop.getName()).get().getOwner())); + channel + .getTags() + .forEach(tag -> tag.setOwner(tagRepository.findById(tag.getName()).get().getOwner())); + + Channel createdChannel = channelRepository.index(channel); + // process the results + channelProcessorService.sendToProcessors(List.of(createdChannel)); + // create new channel + return createdChannel; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Create or replace multiple channels", - description = "Create or replace multiple channel instances.", - operationId = "createOrReplaceChannels", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The created/replaced channels", - content = @Content( - array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag, or property not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping - public Iterable create(@RequestBody Iterable channels) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { - // check if authorized owner - long start = System.currentTimeMillis(); - Map existingChannels = channelRepository.findAllById(StreamSupport - .stream(channels.spliterator(), true) - .map(Channel::getName) - .toList()) - .stream().collect(Collectors.toMap(Channel::getName, channel -> channel)); - for(Channel channel: channels) { - boolean present = existingChannels.containsKey(channel.getName()); - if(present) { - Channel existingChannel = existingChannels.get(channel.getName()); - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingChannel), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, existingChannel, HttpStatus.UNAUTHORIZED); - channel.setOwner(existingChannel.getOwner()); - } else { - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), channel), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channel, HttpStatus.UNAUTHORIZED); - } - } - logger.log(Level.INFO, "Completed Authorization check : " + (System.currentTimeMillis() - start) + "ms"); - start = System.currentTimeMillis(); - // Validate request parameters - validateChannelRequest(channels); - logger.log(Level.INFO, "Completed validation check : " + (System.currentTimeMillis() - start) + "ms"); - start = System.currentTimeMillis(); - - // delete existing channels - channelRepository.deleteAll(channels); - logger.log(Level.INFO, "Completed replacement of Channels : " + (System.currentTimeMillis() - start) + "ms"); - start = System.currentTimeMillis(); - - // reset owners of attached tags/props back to existing owners - resetOwnersToExisting(channels); - - logger.log(Level.INFO, "Completed reset tag and property ownership : " + (System.currentTimeMillis() - start) + "ms"); - start = System.currentTimeMillis(); - - logger.log(Level.INFO, "Completed logging : " + (System.currentTimeMillis() - start) + "ms"); - start = System.currentTimeMillis(); - List createdChannels = channelRepository.indexAll(Lists.newArrayList(channels)); - - logger.log(Level.INFO, "Completed indexing : " + (System.currentTimeMillis() - start) + "ms"); - // process the results - channelProcessorService.sendToProcessors(createdChannels); - // created new channel - return createdChannels; + } + + @Operation( + summary = "Create or replace multiple channels", + description = "Create or replace multiple channel instances.", + operationId = "createOrReplaceChannels", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The created/replaced channels", + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = Channel.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag, or property not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping + public Iterable create(@RequestBody Iterable channels) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { + // check if authorized owner + long start = System.currentTimeMillis(); + Map existingChannels = + channelRepository + .findAllById( + StreamSupport.stream(channels.spliterator(), true).map(Channel::getName).toList()) + .stream() + .collect(Collectors.toMap(Channel::getName, channel -> channel)); + for (Channel channel : channels) { + boolean present = existingChannels.containsKey(channel.getName()); + if (present) { + Channel existingChannel = existingChannels.get(channel.getName()); + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingChannel), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + existingChannel, + HttpStatus.UNAUTHORIZED); + channel.setOwner(existingChannel.getOwner()); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNELS, channels); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), channel), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + channel, + HttpStatus.UNAUTHORIZED); } + } + logger.log( + Level.INFO, + "Completed Authorization check : " + (System.currentTimeMillis() - start) + "ms"); + start = System.currentTimeMillis(); + // Validate request parameters + validateChannelRequest(channels); + logger.log( + Level.INFO, + "Completed validation check : " + (System.currentTimeMillis() - start) + "ms"); + start = System.currentTimeMillis(); + + // delete existing channels + channelRepository.deleteAll(channels); + logger.log( + Level.INFO, + "Completed replacement of Channels : " + (System.currentTimeMillis() - start) + "ms"); + start = System.currentTimeMillis(); + + // reset owners of attached tags/props back to existing owners + resetOwnersToExisting(channels); + + logger.log( + Level.INFO, + "Completed reset tag and property ownership : " + + (System.currentTimeMillis() - start) + + "ms"); + start = System.currentTimeMillis(); + + logger.log(Level.INFO, "Completed logging : " + (System.currentTimeMillis() - start) + "ms"); + start = System.currentTimeMillis(); + List createdChannels = channelRepository.indexAll(Lists.newArrayList(channels)); + + logger.log(Level.INFO, "Completed indexing : " + (System.currentTimeMillis() - start) + "ms"); + // process the results + channelProcessorService.sendToProcessors(createdChannels); + // created new channel + return createdChannels; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNELS, channels); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - private void resetOwnersToExisting(Iterable channels) { - Map propOwners = StreamSupport - .stream(propertyRepository.findAll().spliterator(), true) - .collect(Collectors.toUnmodifiableMap(Property::getName, Property::getOwner)); - Map tagOwners = StreamSupport - .stream(tagRepository.findAll().spliterator(), true) - .collect(Collectors.toUnmodifiableMap(Tag::getName, Tag::getOwner)); - - for(Channel channel: channels) { - channel.getProperties().forEach(prop -> prop.setOwner(propOwners.get(prop.getName()))); - channel.getTags().forEach(tag -> tag.setOwner(tagOwners.get(tag.getName()))); - } + } + + private void resetOwnersToExisting(Iterable channels) { + Map propOwners = + StreamSupport.stream(propertyRepository.findAll().spliterator(), true) + .collect(Collectors.toUnmodifiableMap(Property::getName, Property::getOwner)); + Map tagOwners = + StreamSupport.stream(tagRepository.findAll().spliterator(), true) + .collect(Collectors.toUnmodifiableMap(Tag::getName, Tag::getOwner)); + + for (Channel channel : channels) { + channel.getProperties().forEach(prop -> prop.setOwner(propOwners.get(prop.getName()))); + channel.getTags().forEach(tag -> tag.setOwner(tagOwners.get(tag.getName()))); } - - @Operation( - summary = "Update a channel", - description = "Merge properties and tags of the channel identified by the payload into an existing channel.", - operationId = "updateChannel", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The updated channel", - content = @Content(schema = @Schema(implementation = Channel.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Channel, Tag, or property not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to update channel", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping("/{channelName}") - public Channel update(@PathVariable("channelName") String channelName, @RequestBody Channel channel) { - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { - long start = System.currentTimeMillis(); - - // Validate request parameters - validateChannelRequest(channel); - - final long time = System.currentTimeMillis() - start; - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.PATH_POST_VALIDATION_TIME, servletContext.getContextPath(), time)); - - // check if authorized owner - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), channel), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channel, HttpStatus.UNAUTHORIZED); - Optional existingChannel = channelRepository.findById(channelName); - boolean present = existingChannel.isPresent(); - - Channel newChannel; - if(present) { - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, existingChannel.get(), HttpStatus.UNAUTHORIZED); - newChannel = existingChannel.get(); - newChannel.setOwner(channel.getOwner()); - newChannel.addProperties(channel.getProperties()); - newChannel.addTags(channel.getTags()); - // Is an existing channel being renamed - if (!channel.getName().equalsIgnoreCase(existingChannel.get().getName())) { - // Since this is a rename operation we will need to remove the old channel. - channelRepository.deleteById(existingChannel.get().getName()); - newChannel.setName(channel.getName()); - } - } else { - newChannel = channel; - } - - // reset owners of attached tags/props back to existing owners - channel.getProperties().forEach(prop -> prop.setOwner(propertyRepository.findById(prop.getName()).get().getOwner())); - channel.getTags().forEach(tag -> tag.setOwner(tagRepository.findById(tag.getName()).get().getOwner())); - - Channel updatedChannels = channelRepository.save(newChannel); - // process the results - channelProcessorService.sendToProcessors(List.of(updatedChannels)); - // created new channel - return updatedChannels; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + @Operation( + summary = "Update a channel", + description = + "Merge properties and tags of the channel identified by the payload into an existing channel.", + operationId = "updateChannel", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The updated channel", + content = @Content(schema = @Schema(implementation = Channel.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Channel, Tag, or property not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to update channel", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping("/{channelName}") + public Channel update( + @PathVariable("channelName") String channelName, @RequestBody Channel channel) { + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { + long start = System.currentTimeMillis(); + + // Validate request parameters + validateChannelRequest(channel); + + final long time = System.currentTimeMillis() - start; + channelManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.PATH_POST_VALIDATION_TIME, servletContext.getContextPath(), time)); + + // check if authorized owner + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), channel), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + channel, + HttpStatus.UNAUTHORIZED); + Optional existingChannel = channelRepository.findById(channelName); + boolean present = existingChannel.isPresent(); + + Channel newChannel; + if (present) { + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + existingChannel.get(), + HttpStatus.UNAUTHORIZED); + newChannel = existingChannel.get(); + newChannel.setOwner(channel.getOwner()); + newChannel.addProperties(channel.getProperties()); + newChannel.addTags(channel.getTags()); + // Is an existing channel being renamed + if (!channel.getName().equalsIgnoreCase(existingChannel.get().getName())) { + // Since this is a rename operation we will need to remove the old channel. + channelRepository.deleteById(existingChannel.get().getName()); + newChannel.setName(channel.getName()); } + } else { + newChannel = channel; + } + + // reset owners of attached tags/props back to existing owners + channel + .getProperties() + .forEach( + prop -> prop.setOwner(propertyRepository.findById(prop.getName()).get().getOwner())); + channel + .getTags() + .forEach(tag -> tag.setOwner(tagRepository.findById(tag.getName()).get().getOwner())); + + Channel updatedChannels = channelRepository.save(newChannel); + // process the results + channelProcessorService.sendToProcessors(List.of(updatedChannels)); + // created new channel + return updatedChannels; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Update multiple channels", - description = "Merge properties and tags of the channels identified by the payload into existing channels.", - operationId = "updateChannels", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "The updated channels", - content = @Content(schema = @Schema(implementation = Channel.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Channel not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to update channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping() - public Iterable update(@RequestBody Iterable channels) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { - long start = System.currentTimeMillis(); - - for(Channel channel: channels) { - Optional existingChannel = channelRepository.findById(channel.getName()); - boolean present = existingChannel.isPresent(); - if(present) { - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, existingChannel.get(), HttpStatus.UNAUTHORIZED); - channel.setOwner(existingChannel.get().getOwner()); - } else { - checkAndThrow(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), channel), TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channel, HttpStatus.UNAUTHORIZED); - } - } - - // Validate request parameters - validateChannelRequest(channels); - - final long time = System.currentTimeMillis() - start; - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.PATH_POST_PREPERATION_TIME, servletContext.getContextPath(), time)); - - // reset owners of attached tags/props back to existing owners - resetOwnersToExisting(channels); - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.PATH_POST_PREPERATION_TIME, servletContext.getContextPath(), time)); - - // update channels - List updatedChannels = FluentIterable.from(channelRepository.saveAll(channels)).toList(); - // process the results - channelProcessorService.sendToProcessors(updatedChannels); - // created new channel - return updatedChannels; + } + + @Operation( + summary = "Update multiple channels", + description = + "Merge properties and tags of the channels identified by the payload into existing channels.", + operationId = "updateChannels", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The updated channels", + content = @Content(schema = @Schema(implementation = Channel.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Channel not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to update channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping() + public Iterable update(@RequestBody Iterable channels) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { + long start = System.currentTimeMillis(); + + for (Channel channel : channels) { + Optional existingChannel = channelRepository.findById(channel.getName()); + boolean present = existingChannel.isPresent(); + if (present) { + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingChannel.get()), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + existingChannel.get(), + HttpStatus.UNAUTHORIZED); + channel.setOwner(existingChannel.get().getOwner()); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNELS, channels); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + checkAndThrow( + !authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), channel), + TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, + channel, + HttpStatus.UNAUTHORIZED); } + } + + // Validate request parameters + validateChannelRequest(channels); + + final long time = System.currentTimeMillis() - start; + channelManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.PATH_POST_PREPERATION_TIME, servletContext.getContextPath(), time)); + + // reset owners of attached tags/props back to existing owners + resetOwnersToExisting(channels); + channelManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.PATH_POST_PREPERATION_TIME, servletContext.getContextPath(), time)); + + // update channels + List updatedChannels = + FluentIterable.from(channelRepository.saveAll(channels)).toList(); + // process the results + channelProcessorService.sendToProcessors(updatedChannels); + // created new channel + return updatedChannels; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNELS, channels); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Delete a channel", - description = "Delete a channel instance identified by its name.", - operationId = "deleteChannel", - tags = {"Channel"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Channel deleted"), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Channel not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to delete channel", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @DeleteMapping("/{channelName}") - public void remove(@PathVariable("channelName") String channelName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { - channelManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.DELETE_CHANNEL, channelName)); - Optional existingChannel = channelRepository.findById(channelName); - if(existingChannel.isPresent()) { - // check if authorized owner - if(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingChannel.get())) { - // delete channel - channelRepository.deleteById(channelName); - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } else { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + @Operation( + summary = "Delete a channel", + description = "Delete a channel instance identified by its name.", + operationId = "deleteChannel", + tags = {"Channel"}) + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Channel deleted"), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Channel not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to delete channel", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @DeleteMapping("/{channelName}") + public void remove(@PathVariable("channelName") String channelName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL)) { + channelManagerAudit.log( + Level.INFO, () -> MessageFormat.format(TextUtil.DELETE_CHANNEL, channelName)); + Optional existingChannel = channelRepository.findById(channelName); + if (existingChannel.isPresent()) { + // check if authorized owner + if (authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingChannel.get())) { + // delete channel + channelRepository.deleteById(channelName); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } else { + String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_CHANNEL, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - /** - * Checks if - * 1. the channel name is not null and matches the name in the body - * 2. the channel owner is not null or empty - * 3. all the listed tags/props exist and prop value is not null or empty - * - * @param channel channel to be validated - */ - public void validateChannelRequest(Channel channel) { - // 1 - checkAndThrow(channel.getName() == null || channel.getName().isEmpty(), TextUtil.CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY, channel, HttpStatus.BAD_REQUEST); - // 2 - checkAndThrow(channel.getOwner() == null || channel.getOwner().isEmpty(), TextUtil.CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY, channel, HttpStatus.BAD_REQUEST); - // 3 - checkTags(channel); - // 3 - checkProperties(channel); + } + + /** + * Checks if 1. the channel name is not null and matches the name in the body 2. the channel owner + * is not null or empty 3. all the listed tags/props exist and prop value is not null or empty + * + * @param channel channel to be validated + */ + public void validateChannelRequest(Channel channel) { + // 1 + checkAndThrow( + channel.getName() == null || channel.getName().isEmpty(), + TextUtil.CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY, + channel, + HttpStatus.BAD_REQUEST); + // 2 + checkAndThrow( + channel.getOwner() == null || channel.getOwner().isEmpty(), + TextUtil.CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY, + channel, + HttpStatus.BAD_REQUEST); + // 3 + checkTags(channel); + // 3 + checkProperties(channel); + } + + private void checkProperties(Channel channel) { + List propertyNames = channel.getProperties().stream().map(Property::getName).toList(); + List propertyValues = channel.getProperties().stream().map(Property::getValue).toList(); + for (String propertyName : propertyNames) { + if (!propertyRepository.existsById(propertyName)) { + String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } } - - private void checkProperties(Channel channel) { - List propertyNames = channel.getProperties().stream().map(Property::getName).toList(); - List propertyValues = channel.getProperties().stream().map(Property::getValue).toList(); - for(String propertyName:propertyNames) { - if(!propertyRepository.existsById(propertyName)) { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } - checkValues(propertyNames, propertyValues); + checkValues(propertyNames, propertyValues); + } + + private void checkValues(List propertyNames, List propertyValues) { + for (String propertyValue : propertyValues) { + if (propertyValue == null || propertyValue.isEmpty()) { + String message = + MessageFormat.format( + TextUtil.PROPERTY_VALUE_NULL_OR_EMPTY, + propertyNames.get(propertyValues.indexOf(propertyValue)), + propertyValue); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); + } } - - private void checkValues(List propertyNames, List propertyValues) { - for(String propertyValue:propertyValues) { - if(propertyValue == null || propertyValue.isEmpty()) { - String message = MessageFormat.format(TextUtil.PROPERTY_VALUE_NULL_OR_EMPTY, propertyNames.get(propertyValues.indexOf(propertyValue)), propertyValue); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); - } - } + } + + private void checkTags(Channel channel) { + List tagNames = channel.getTags().stream().map(Tag::getName).toList(); + for (String tagName : tagNames) { + if (!tagRepository.existsById(tagName)) { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } } - - private void checkTags(Channel channel) { - List tagNames = channel.getTags().stream().map(Tag::getName).toList(); - for(String tagName:tagNames) { - if(!tagRepository.existsById(tagName)) { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } + } + + private static void checkAndThrow( + boolean channel, + String channelNameCannotBeNullOrEmpty, + Channel channel1, + HttpStatus badRequest) { + if (channel) { + String message = MessageFormat.format(channelNameCannotBeNullOrEmpty, channel1.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(badRequest)); + throw new ResponseStatusException(badRequest, message, null); } - - private static void checkAndThrow(boolean channel, String channelNameCannotBeNullOrEmpty, Channel channel1, HttpStatus badRequest) { - if (channel) { - String message = MessageFormat.format(channelNameCannotBeNullOrEmpty, channel1.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(badRequest)); - throw new ResponseStatusException(badRequest, message, null); + } + + /** + * Checks if 1. the tag names are not null 2. the tag owners are not null or empty 3. all the + * channels exist + * + * @param channels list of channels to be validated + */ + public void validateChannelRequest(Iterable channels) { + List existingProperties = + StreamSupport.stream(propertyRepository.findAll().spliterator(), true) + .map(Property::getName) + .toList(); + List existingTags = + StreamSupport.stream(tagRepository.findAll().spliterator(), true) + .map(Tag::getName) + .toList(); + for (Channel channel : channels) { + // 1 + checkAndThrow( + channel.getName() == null || channel.getName().isEmpty(), + TextUtil.CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY, + channel, + HttpStatus.BAD_REQUEST); + // 2 + checkAndThrow( + channel.getOwner() == null || channel.getOwner().isEmpty(), + TextUtil.CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY, + channel, + HttpStatus.BAD_REQUEST); + // 3 + List tagNames = channel.getTags().stream().map(Tag::getName).toList(); + for (String tagName : tagNames) { + if (!existingTags.contains(tagName)) { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); } - } - - /** - * Checks if - * 1. the tag names are not null - * 2. the tag owners are not null or empty - * 3. all the channels exist - * - * @param channels list of channels to be validated - */ - public void validateChannelRequest(Iterable channels) { - List existingProperties = StreamSupport - .stream(propertyRepository.findAll().spliterator(), true) - .map(Property::getName) - .toList(); - List existingTags = StreamSupport - .stream(tagRepository.findAll().spliterator(), true) - .map(Tag::getName) - .toList(); - for(Channel channel: channels) { - // 1 - checkAndThrow(channel.getName() == null || channel.getName().isEmpty(), TextUtil.CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY, channel, HttpStatus.BAD_REQUEST); - // 2 - checkAndThrow(channel.getOwner() == null || channel.getOwner().isEmpty(), TextUtil.CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY, channel, HttpStatus.BAD_REQUEST); - // 3 - List tagNames = channel.getTags().stream().map(Tag::getName).toList(); - for(String tagName:tagNames) { - if(!existingTags.contains(tagName)) { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } - // 3 - List propertyNames = channel.getProperties().stream().map(Property::getName).toList(); - List propertyValues = channel.getProperties().stream().map(Property::getValue).toList(); - for(String propertyName:propertyNames) { - if(!existingProperties.contains(propertyName)) { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } - checkValues(propertyNames, propertyValues); + } + // 3 + List propertyNames = channel.getProperties().stream().map(Property::getName).toList(); + List propertyValues = + channel.getProperties().stream().map(Property::getValue).toList(); + for (String propertyName : propertyNames) { + if (!existingProperties.contains(propertyName)) { + String message = + MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); } + } + checkValues(propertyNames, propertyValues); } - + } } diff --git a/src/main/java/org/phoebus/channelfinder/ChannelRepository.java b/src/main/java/org/phoebus/channelfinder/ChannelRepository.java index ac671e3c..c30b6399 100644 --- a/src/main/java/org/phoebus/channelfinder/ChannelRepository.java +++ b/src/main/java/org/phoebus/channelfinder/ChannelRepository.java @@ -29,6 +29,18 @@ import co.elastic.clients.json.JsonData; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.entity.SearchResult; @@ -43,602 +55,654 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.text.MessageFormat; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - @Repository @Configuration public class ChannelRepository implements CrudRepository { - private static final Logger logger = Logger.getLogger(ChannelRepository.class.getName()); - - @Autowired - ElasticConfig esService; - - @Autowired - @Qualifier("indexClient") - ElasticsearchClient client; - - final ObjectMapper objectMapper = new ObjectMapper() - .addMixIn(Tag.class, Tag.OnlyTag.class) - .addMixIn(Property.class, Property.OnlyProperty.class); - - /** - * create a new channel using the given Channel - * - * @param channel - channel to be created - * @return the created channel - */ - @SuppressWarnings("unchecked") - public Channel index(Channel channel) { - try { - IndexRequest request = IndexRequest.of(i -> i.index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))) - .refresh(Refresh.True)); - IndexResponse response = client.index(request); - // verify the creation of the tag - if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); - return findById(channel.getName()).get(); - } - } 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); - } - return null; + private static final Logger logger = Logger.getLogger(ChannelRepository.class.getName()); + + @Autowired ElasticConfig esService; + + @Autowired + @Qualifier("indexClient") + ElasticsearchClient client; + + final ObjectMapper objectMapper = + new ObjectMapper() + .addMixIn(Tag.class, Tag.OnlyTag.class) + .addMixIn(Property.class, Property.OnlyProperty.class); + + /** + * create a new channel using the given Channel + * + * @param channel - channel to be created + * @return the created channel + */ + @SuppressWarnings("unchecked") + public Channel index(Channel channel) { + try { + IndexRequest request = + IndexRequest.of( + i -> + i.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))) + .refresh(Refresh.True)); + IndexResponse response = client.index(request); + // verify the creation of the tag + if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); + return findById(channel.getName()).get(); + } + } 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); } - - /** - * create new channels using the given XmlChannels - * - * @param channels - channels to be created - * @return the created channels - */ - public List indexAll(List channels) { - BulkRequest.Builder br = new BulkRequest.Builder(); - - for (Channel channel : channels) { - br.operations(op -> op - .index(idx -> idx - .index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))) - ) - ).refresh(Refresh.True); - } - - BulkResponse result = null; - try { - result = client.bulk(br.build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - // TODO cleanup? or throw exception? - } else { - return channels; - } - } catch (IOException e) { - 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); - - } - return Collections.emptyList(); + return null; + } + + /** + * create new channels using the given XmlChannels + * + * @param channels - channels to be created + * @return the created channels + */ + public List indexAll(List channels) { + BulkRequest.Builder br = new BulkRequest.Builder(); + + for (Channel channel : channels) { + br.operations( + op -> + op.index( + idx -> + idx.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .document( + JsonData.of(channel, new JacksonJsonpMapper(objectMapper))))) + .refresh(Refresh.True); } - /** - * update/save channel using the given Channel - * - * @param channelName - name of channel to be saved - * @param channel - channel to be saved - * @return the updated/saved channel - */ - public Channel save(String channelName, Channel channel) { - try { - IndexResponse response = client.index(i -> i.index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))) - .refresh(Refresh.True)); - // verify the creation of the channel - if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); - return findById(channel.getName()).get(); - } - } 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); + BulkResponse result = null; + try { + result = client.bulk(br.build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - return null; + // TODO cleanup? or throw exception? + } else { + return channels; + } + } catch (IOException e) { + 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); } - - /** - * - */ - @Override - public Channel save(Channel channel) { - return save(channel.getName(),channel); + return Collections.emptyList(); + } + + /** + * update/save channel using the given Channel + * + * @param channelName - name of channel to be saved + * @param channel - channel to be saved + * @return the updated/saved channel + */ + public Channel save(String channelName, Channel channel) { + try { + IndexResponse response = + client.index( + i -> + i.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))) + .refresh(Refresh.True)); + // verify the creation of the channel + if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_CHANNEL, channel.toLog())); + return findById(channel.getName()).get(); + } + } 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); } - - /** - * update/save channels using the given XmlChannels - * - * @param extends Channel - * @param channels - channels to be saved - * @return the updated/saved channels - */ - @SuppressWarnings("unchecked") - @Override - public Iterable saveAll(Iterable channels) { - // Create a list of all channel names - List ids = StreamSupport.stream(channels.spliterator(), false).map(Channel::getName).collect(Collectors.toList()); - - try { - Map existingChannels = findAllById(ids).stream().collect(Collectors.toMap(Channel::getName, c -> c)); - - BulkRequest.Builder br = new BulkRequest.Builder(); - - for (Channel channel : channels) { - if (existingChannels.containsKey(channel.getName())) { - // merge with existing channel - Channel updatedChannel = existingChannels.get(channel.getName()); - if (channel.getOwner() != null && !channel.getOwner().isEmpty()) - updatedChannel.setOwner(channel.getOwner()); - updatedChannel.addProperties(channel.getProperties()); - updatedChannel.addTags(channel.getTags()); - br.operations(op -> op.index(i -> i.index(esService.getES_CHANNEL_INDEX()) - .id(updatedChannel.getName()) - .document(JsonData.of(updatedChannel, new JacksonJsonpMapper(objectMapper))))); - } else { - br.operations(op -> op.index(i -> i.index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .document(JsonData.of(channel, new JacksonJsonpMapper(objectMapper))))); - } - - } - BulkResponse result = null; - result = client.bulk(br.refresh(Refresh.True).build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - // TODO cleanup? or throw exception? - } else { - return (Iterable) findAllById(ids); - } - } catch (IOException e) { - 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); - + return null; + } + + /** */ + @Override + public Channel save(Channel channel) { + return save(channel.getName(), channel); + } + + /** + * update/save channels using the given XmlChannels + * + * @param extends Channel + * @param channels - channels to be saved + * @return the updated/saved channels + */ + @SuppressWarnings("unchecked") + @Override + public Iterable saveAll(Iterable channels) { + // Create a list of all channel names + List ids = + StreamSupport.stream(channels.spliterator(), false) + .map(Channel::getName) + .collect(Collectors.toList()); + + try { + Map existingChannels = + findAllById(ids).stream().collect(Collectors.toMap(Channel::getName, c -> c)); + + BulkRequest.Builder br = new BulkRequest.Builder(); + + for (Channel channel : channels) { + if (existingChannels.containsKey(channel.getName())) { + // merge with existing channel + Channel updatedChannel = existingChannels.get(channel.getName()); + if (channel.getOwner() != null && !channel.getOwner().isEmpty()) + updatedChannel.setOwner(channel.getOwner()); + updatedChannel.addProperties(channel.getProperties()); + updatedChannel.addTags(channel.getTags()); + br.operations( + op -> + op.index( + i -> + i.index(esService.getES_CHANNEL_INDEX()) + .id(updatedChannel.getName()) + .document( + JsonData.of( + updatedChannel, new JacksonJsonpMapper(objectMapper))))); + } else { + br.operations( + op -> + op.index( + i -> + i.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .document( + JsonData.of(channel, new JacksonJsonpMapper(objectMapper))))); } - return null; - } - - /** - * find channel using the given channel id - * - * @param channelName - name of channel to be found - * @return the found channel - */ - @Override - public Optional findById(String channelName) { - GetResponse response; - try { - response = client.get(g -> g.index(esService.getES_CHANNEL_INDEX()).id(channelName), Channel.class); - - if (response.found()) { - Channel channel = response.source(); - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CHANNEL_FOUND, channel.getName())); - return Optional.of(channel); - } else { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CHANNEL_NOT_FOUND, channelName)); - return Optional.empty(); - } - } 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); + } + BulkResponse result = null; + result = client.bulk(br.refresh(Refresh.True).build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } + // TODO cleanup? or throw exception? + } else { + return (Iterable) findAllById(ids); + } + } catch (IOException e) { + 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); } - - /** - * Find all channels with given ids - * @param channelIds - list of channel ids to verify exists - * @return true if all the channel id's exist - */ - public boolean existsByIds(List channelIds) { - try { - List ids = StreamSupport.stream(channelIds.spliterator(), false).collect(Collectors.toList()); - - SearchRequest.Builder searchBuilder = new SearchRequest.Builder() - .index(esService.getES_CHANNEL_INDEX()) - .query(IdsQuery.of(q -> q.values(ids))._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Channel.class); - return new HashSet<>(response.hits() - .hits().stream().map(h -> h.source().getName()).collect(Collectors.toList())) - .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); - } + return null; + } + + /** + * find channel using the given channel id + * + * @param channelName - name of channel to be found + * @return the found channel + */ + @Override + public Optional findById(String channelName) { + GetResponse response; + try { + response = + client.get(g -> g.index(esService.getES_CHANNEL_INDEX()).id(channelName), Channel.class); + + if (response.found()) { + Channel channel = response.source(); + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.CHANNEL_FOUND, channel.getName())); + return Optional.of(channel); + } else { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.CHANNEL_NOT_FOUND, channelName)); + return Optional.empty(); + } + } 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); } - - /** - * Check is channel with name 'channelName' exists - * @param channelName - * @return true if channel exists - */ - @Override - public boolean existsById(String channelName) { - try { - ExistsRequest.Builder builder = new ExistsRequest.Builder(); - builder.index(esService.getES_CHANNEL_INDEX()).id(channelName); - return client.exists(builder.build()).value(); - } catch (ElasticsearchException | IOException e) { - 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); - } + } + + /** + * Find all channels with given ids + * + * @param channelIds - list of channel ids to verify exists + * @return true if all the channel id's exist + */ + public boolean existsByIds(List channelIds) { + try { + List ids = + StreamSupport.stream(channelIds.spliterator(), false).collect(Collectors.toList()); + + SearchRequest.Builder searchBuilder = + new SearchRequest.Builder() + .index(esService.getES_CHANNEL_INDEX()) + .query(IdsQuery.of(q -> q.values(ids))._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Channel.class); + return new HashSet<>( + response.hits().hits().stream() + .map(h -> h.source().getName()) + .collect(Collectors.toList())) + .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); } - - /** - * find all channels - * - * @return the found channels - */ - @Override - public Iterable findAll() { - throw new UnsupportedOperationException(TextUtil.FIND_ALL_CHANNELS_NOT_SUPPORTED); + } + + /** + * Check is channel with name 'channelName' exists + * + * @param channelName + * @return true if channel exists + */ + @Override + public boolean existsById(String channelName) { + try { + ExistsRequest.Builder builder = new ExistsRequest.Builder(); + builder.index(esService.getES_CHANNEL_INDEX()).id(channelName); + return client.exists(builder.build()).value(); + } catch (ElasticsearchException | IOException e) { + 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); } - - /** - * find channels using the given channels ids - * - * @param channelIds - ids of channels to be found - * @return the found channels - */ - @Override - public List findAllById(Iterable channelIds) { - try { - List ids = StreamSupport.stream(channelIds.spliterator(), false).collect(Collectors.toList()); - - SearchRequest.Builder searchBuilder = new SearchRequest.Builder() - .index(esService.getES_CHANNEL_INDEX()) - .query(IdsQuery.of(q -> q.values(ids))._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Channel.class); - 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); - } + } + + /** + * find all channels + * + * @return the found channels + */ + @Override + public Iterable findAll() { + throw new UnsupportedOperationException(TextUtil.FIND_ALL_CHANNELS_NOT_SUPPORTED); + } + + /** + * find channels using the given channels ids + * + * @param channelIds - ids of channels to be found + * @return the found channels + */ + @Override + public List findAllById(Iterable channelIds) { + try { + List ids = + StreamSupport.stream(channelIds.spliterator(), false).collect(Collectors.toList()); + + SearchRequest.Builder searchBuilder = + new SearchRequest.Builder() + .index(esService.getES_CHANNEL_INDEX()) + .query(IdsQuery.of(q -> q.values(ids))._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Channel.class); + 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); } - - @Override - public long count() { - return this.count(new LinkedMultiValueMap<>()); + } + + @Override + public long count() { + return this.count(new LinkedMultiValueMap<>()); + } + + /** + * delete the given channel by channel name + * + * @param channelName - channel to be deleted + */ + @Override + public void deleteById(String channelName) { + try { + DeleteResponse response = + client.delete( + i -> i.index(esService.getES_CHANNEL_INDEX()).id(channelName).refresh(Refresh.True)); + // verify the deletion of the channel + if (response.result().equals(Result.Deleted)) { + logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.DELETE_CHANNEL, 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); } - - /** - * delete the given channel by channel name - * - * @param channelName - channel to be deleted - */ - @Override - public void deleteById(String channelName) { - try { - DeleteResponse response = client - .delete(i -> i.index(esService.getES_CHANNEL_INDEX()).id(channelName).refresh(Refresh.True)); - // verify the deletion of the channel - if (response.result().equals(Result.Deleted)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.DELETE_CHANNEL, 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); - } + } + + /** + * delete the given channel + * + * @param channel - channel to be deleted + */ + @Override + public void delete(Channel channel) { + deleteById(channel.getName()); + } + + @Override + public void deleteAll(Iterable channels) { + + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Channel channel : channels) { + br.operations( + op -> + op.delete( + idx -> idx.index(esService.getES_CHANNEL_INDEX()).id(channel.getName()))) + .refresh(Refresh.True); } - - /** - * delete the given channel - * - * @param channel - channel to be deleted - */ - @Override - public void delete(Channel channel) { - deleteById(channel.getName()); + try { + BulkResponse result = client.bulk(br.build()); + } catch (IOException e) { + logger.log(Level.WARNING, e.getMessage(), e); } - - @Override - public void deleteAll(Iterable channels) { - - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Channel channel : channels) { - br.operations(op -> op - . delete(idx -> idx - .index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName())) - ).refresh(Refresh.True); - } - try { - BulkResponse result = client.bulk(br.build()); - } catch (IOException e) { - logger.log(Level.WARNING, e.getMessage(), e); - } - } - - @Override - public void deleteAll() { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - - - /** - * Search for a list of channels based on their name, tags, and/or properties. - * Search parameters ~name - The name of the channel ~tags - A list of comma - * separated values ${propertyName}:${propertyValue} - - *

- * The query result is sorted based on the channel name ~size - The number of - * channels to be returned ~from - The starting index of the channel list - * - * @param searchParameters channel search parameters - * @return matching channels - */ - public SearchResult search(MultiValueMap searchParameters) { - BuiltQuery builtQuery = getBuiltQuery(searchParameters); - Integer finalSize = builtQuery.size; - Integer finalFrom = builtQuery.from; - - if(builtQuery.size + builtQuery.from > esService.getES_MAX_RESULT_WINDOW_SIZE()) { - String message = MessageFormat.format(TextUtil.SEARCH_FAILED_CAUSE, - searchParameters, - "Max search window exceeded, use the " + CFResourceDescriptors.SCROLL_RESOURCE_URI + " api."); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); - } - - try { - SearchRequest.Builder searchBuilder = new SearchRequest.Builder(); - searchBuilder.index(esService.getES_CHANNEL_INDEX()) - .query(builtQuery.boolQuery.build()._toQuery()) - .from(finalFrom) - .size(finalSize) - .trackTotalHits(builder -> builder.enabled(builtQuery.trackTotalHits)) - .sort(SortOptions.of(o -> o.field(FieldSort.of(f -> f.field("name"))))); - builtQuery.searchAfter.ifPresent(s -> searchBuilder.searchAfter(FieldValue.of(s))); - - SearchResponse response = client.search(searchBuilder.build(), - Channel.class - ); - - List> hits = response.hits().hits(); - long count = hits.size(); - if (builtQuery.trackTotalHits) { - assert response.hits().total() != null; - count = response.hits().total().value(); - } - return new SearchResult(hits.stream().map(Hit::source).collect(Collectors.toList()), count); - } catch (Exception e) { - 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); - } + } + + @Override + public void deleteAll() { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } + + /** + * Search for a list of channels based on their name, tags, and/or properties. Search parameters + * ~name - The name of the channel ~tags - A list of comma separated values + * ${propertyName}:${propertyValue} - + * + *

The query result is sorted based on the channel name ~size - The number of channels to be + * returned ~from - The starting index of the channel list + * + * @param searchParameters channel search parameters + * @return matching channels + */ + public SearchResult search(MultiValueMap searchParameters) { + BuiltQuery builtQuery = getBuiltQuery(searchParameters); + Integer finalSize = builtQuery.size; + Integer finalFrom = builtQuery.from; + + if (builtQuery.size + builtQuery.from > esService.getES_MAX_RESULT_WINDOW_SIZE()) { + String message = + MessageFormat.format( + TextUtil.SEARCH_FAILED_CAUSE, + searchParameters, + "Max search window exceeded, use the " + + CFResourceDescriptors.SCROLL_RESOURCE_URI + + " api."); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); } - private BuiltQuery getBuiltQuery(MultiValueMap searchParameters) { - BoolQuery.Builder boolQuery = new BoolQuery.Builder(); - int size = esService.getES_QUERY_SIZE(); - int from = 0; - boolean trackTotalHits = false; - Optional searchAfter = Optional.empty(); - String valueSplitPattern = "[|,;]"; - for (Map.Entry> parameter : searchParameters.entrySet()) { - String key = parameter.getKey().trim(); - boolean isNot = key.endsWith("!"); - if (isNot) { - key = key.substring(0, key.length() - 1); - } - switch (key) { - case "~name": - addNameQuery(parameter, valueSplitPattern, boolQuery); - break; - case "~tag": - addTagsQuery(parameter, valueSplitPattern, isNot, boolQuery); - break; - case "~size": - size = parseCountParameter(parameter, size); - break; - case "~from": - from = parseCountParameter(parameter, from); - break; - case "~search_after": - searchAfter = parameter.getValue().stream().findFirst(); - break; - - case "~track_total_hits": - trackTotalHits = isTrackTotalHits(parameter, trackTotalHits); - break; - default: - DisMaxQuery.Builder propertyQuery = calculatePropertiesQuery(parameter, valueSplitPattern, key, isNot); - boolQuery.must(propertyQuery.build()._toQuery()); - break; - } - } - return new BuiltQuery(boolQuery, size, from, searchAfter, trackTotalHits); - } - - private static DisMaxQuery.Builder calculatePropertiesQuery(Map.Entry> parameter, String valueSplitPattern, String key, boolean isNot) { - DisMaxQuery.Builder propertyQuery = new DisMaxQuery.Builder(); - for (String value : parameter.getValue()) { - for (String pattern : value.split(valueSplitPattern)) { - BoolQuery bq; - bq = calculatePropertyQuery(key, isNot, pattern); - addPropertyQuery(isNot, pattern, propertyQuery, bq); - } - } - return propertyQuery; + try { + SearchRequest.Builder searchBuilder = new SearchRequest.Builder(); + searchBuilder + .index(esService.getES_CHANNEL_INDEX()) + .query(builtQuery.boolQuery.build()._toQuery()) + .from(finalFrom) + .size(finalSize) + .trackTotalHits(builder -> builder.enabled(builtQuery.trackTotalHits)) + .sort(SortOptions.of(o -> o.field(FieldSort.of(f -> f.field("name"))))); + builtQuery.searchAfter.ifPresent(s -> searchBuilder.searchAfter(FieldValue.of(s))); + + SearchResponse response = client.search(searchBuilder.build(), Channel.class); + + List> hits = response.hits().hits(); + long count = hits.size(); + if (builtQuery.trackTotalHits) { + assert response.hits().total() != null; + count = response.hits().total().value(); + } + return new SearchResult(hits.stream().map(Hit::source).collect(Collectors.toList()), count); + } catch (Exception e) { + 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); } - - private static void addPropertyQuery(boolean isNot, String pattern, DisMaxQuery.Builder propertyQuery, BoolQuery bq) { - if (isNot && pattern.trim().equals("*")) { - - propertyQuery.queries( - BoolQuery.of( p -> p.mustNot( - NestedQuery.of(n -> n.path("properties").query(bq._toQuery()))._toQuery() - ))._toQuery() - ); - } else { - - propertyQuery.queries( - NestedQuery.of(n -> n.path("properties").query(bq._toQuery()))._toQuery() - ); - } + } + + private BuiltQuery getBuiltQuery(MultiValueMap searchParameters) { + BoolQuery.Builder boolQuery = new BoolQuery.Builder(); + int size = esService.getES_QUERY_SIZE(); + int from = 0; + boolean trackTotalHits = false; + Optional searchAfter = Optional.empty(); + String valueSplitPattern = "[|,;]"; + for (Map.Entry> parameter : searchParameters.entrySet()) { + String key = parameter.getKey().trim(); + boolean isNot = key.endsWith("!"); + if (isNot) { + key = key.substring(0, key.length() - 1); + } + switch (key) { + case "~name": + addNameQuery(parameter, valueSplitPattern, boolQuery); + break; + case "~tag": + addTagsQuery(parameter, valueSplitPattern, isNot, boolQuery); + break; + case "~size": + size = parseCountParameter(parameter, size); + break; + case "~from": + from = parseCountParameter(parameter, from); + break; + case "~search_after": + searchAfter = parameter.getValue().stream().findFirst(); + break; + + case "~track_total_hits": + trackTotalHits = isTrackTotalHits(parameter, trackTotalHits); + break; + default: + DisMaxQuery.Builder propertyQuery = + calculatePropertiesQuery(parameter, valueSplitPattern, key, isNot); + boolQuery.must(propertyQuery.build()._toQuery()); + break; + } } - - private static BoolQuery calculatePropertyQuery(String key, boolean isNot, String pattern) { + return new BuiltQuery(boolQuery, size, from, searchAfter, trackTotalHits); + } + + private static DisMaxQuery.Builder calculatePropertiesQuery( + Map.Entry> parameter, + String valueSplitPattern, + String key, + boolean isNot) { + DisMaxQuery.Builder propertyQuery = new DisMaxQuery.Builder(); + for (String value : parameter.getValue()) { + for (String pattern : value.split(valueSplitPattern)) { BoolQuery bq; - if (isNot) { - if (pattern.trim().equals("*")) { - bq = BoolQuery.of(p -> p.must(getSingleValueQuery("properties.name", key))); - } else { - bq = BoolQuery.of(p -> p.must(getSingleValueQuery("properties.name", key)) - .mustNot(getSingleValueQuery("properties.value", pattern.trim()))); - } - } else { - bq = BoolQuery.of(p -> p.must(getSingleValueQuery("properties.name", key)) - .must(getSingleValueQuery("properties.value", pattern.trim()))); - } - return bq; + bq = calculatePropertyQuery(key, isNot, pattern); + addPropertyQuery(isNot, pattern, propertyQuery, bq); + } } - - private static boolean isTrackTotalHits(Map.Entry> parameter, boolean trackTotalHits) { - Optional firstTrackTotalHits = parameter.getValue().stream().findFirst(); - if (firstTrackTotalHits.isPresent()) { - trackTotalHits = Boolean.parseBoolean(firstTrackTotalHits.get()); - } - return trackTotalHits; + return propertyQuery; + } + + private static void addPropertyQuery( + boolean isNot, String pattern, DisMaxQuery.Builder propertyQuery, BoolQuery bq) { + if (isNot && pattern.trim().equals("*")) { + + propertyQuery.queries( + BoolQuery.of( + p -> + p.mustNot( + NestedQuery.of(n -> n.path("properties").query(bq._toQuery())) + ._toQuery())) + ._toQuery()); + } else { + + propertyQuery.queries( + NestedQuery.of(n -> n.path("properties").query(bq._toQuery()))._toQuery()); } - - private static int parseCountParameter(Map.Entry> parameter, int size) { - Optional maxSize = parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); - if (maxSize.isPresent()) { - size = Integer.parseInt(maxSize.get()); - } - return size; + } + + private static BoolQuery calculatePropertyQuery(String key, boolean isNot, String pattern) { + BoolQuery bq; + if (isNot) { + if (pattern.trim().equals("*")) { + bq = BoolQuery.of(p -> p.must(getSingleValueQuery("properties.name", key))); + } else { + bq = + BoolQuery.of( + p -> + p.must(getSingleValueQuery("properties.name", key)) + .mustNot(getSingleValueQuery("properties.value", pattern.trim()))); + } + } else { + bq = + BoolQuery.of( + p -> + p.must(getSingleValueQuery("properties.name", key)) + .must(getSingleValueQuery("properties.value", pattern.trim()))); } - - private static void addTagsQuery(Map.Entry> parameter, String valueSplitPattern, boolean isNot, BoolQuery.Builder boolQuery) { - for (String value : parameter.getValue()) { - DisMaxQuery.Builder tagQuery = new DisMaxQuery.Builder(); - for (String pattern : value.split(valueSplitPattern)) { - tagQuery.queries( - NestedQuery.of(n -> n.path("tags").query( - getSingleValueQuery("tags.name", pattern.trim())))._toQuery()); - } - if (isNot) { - boolQuery.mustNot(tagQuery.build()._toQuery()); - } else { - boolQuery.must(tagQuery.build()._toQuery()); - } - - } + return bq; + } + + private static boolean isTrackTotalHits( + Map.Entry> parameter, boolean trackTotalHits) { + Optional firstTrackTotalHits = parameter.getValue().stream().findFirst(); + if (firstTrackTotalHits.isPresent()) { + trackTotalHits = Boolean.parseBoolean(firstTrackTotalHits.get()); } - - private static void addNameQuery(Map.Entry> parameter, String valueSplitPattern, BoolQuery.Builder boolQuery) { - for (String value : parameter.getValue()) { - DisMaxQuery.Builder nameQuery = new DisMaxQuery.Builder(); - for (String pattern : value.split(valueSplitPattern)) { - nameQuery.queries(getSingleValueQuery("name", pattern.trim())); - } - boolQuery.must(nameQuery.build()._toQuery()); - } + return trackTotalHits; + } + + private static int parseCountParameter(Map.Entry> parameter, int size) { + Optional maxSize = + parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); + if (maxSize.isPresent()) { + size = Integer.parseInt(maxSize.get()); } - - private static Query getSingleValueQuery(String name, String pattern) { - return WildcardQuery.of(w -> w.field(name).caseInsensitive(true).value(pattern))._toQuery(); + return size; + } + + private static void addTagsQuery( + Map.Entry> parameter, + String valueSplitPattern, + boolean isNot, + BoolQuery.Builder boolQuery) { + for (String value : parameter.getValue()) { + DisMaxQuery.Builder tagQuery = new DisMaxQuery.Builder(); + for (String pattern : value.split(valueSplitPattern)) { + tagQuery.queries( + NestedQuery.of( + n -> n.path("tags").query(getSingleValueQuery("tags.name", pattern.trim()))) + ._toQuery()); + } + if (isNot) { + boolQuery.mustNot(tagQuery.build()._toQuery()); + } else { + boolQuery.must(tagQuery.build()._toQuery()); + } } - - private record BuiltQuery(BoolQuery.Builder boolQuery, Integer size, Integer from, Optional searchAfter, - boolean trackTotalHits) { + } + + private static void addNameQuery( + Map.Entry> parameter, + String valueSplitPattern, + BoolQuery.Builder boolQuery) { + for (String value : parameter.getValue()) { + DisMaxQuery.Builder nameQuery = new DisMaxQuery.Builder(); + for (String pattern : value.split(valueSplitPattern)) { + nameQuery.queries(getSingleValueQuery("name", pattern.trim())); + } + boolQuery.must(nameQuery.build()._toQuery()); } - - /** - * Match count - * @param searchParameters channel search parameters - * @return count of the number of matches to the provided query - */ - public long count(MultiValueMap searchParameters) { - BuiltQuery builtQuery = getBuiltQuery(searchParameters); - - try { - - CountRequest.Builder countBuilder = new CountRequest.Builder(); - countBuilder.index(esService.getES_CHANNEL_INDEX()).query(builtQuery.boolQuery.build()._toQuery()); - CountResponse response = client.count(countBuilder.build()); - - return response.count(); - } catch (Exception e) { - 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); - } - } - - - /** - * Match count - * @param propertyName channel search property name - * @param propertyValue channel search property value - * @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); - } - - /** - * Match count - * @param tagName channel search tag - * @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); + } + + private static Query getSingleValueQuery(String name, String pattern) { + return WildcardQuery.of(w -> w.field(name).caseInsensitive(true).value(pattern))._toQuery(); + } + + private record BuiltQuery( + BoolQuery.Builder boolQuery, + Integer size, + Integer from, + Optional searchAfter, + boolean trackTotalHits) {} + + /** + * Match count + * + * @param searchParameters channel search parameters + * @return count of the number of matches to the provided query + */ + public long count(MultiValueMap searchParameters) { + BuiltQuery builtQuery = getBuiltQuery(searchParameters); + + try { + + CountRequest.Builder countBuilder = new CountRequest.Builder(); + countBuilder + .index(esService.getES_CHANNEL_INDEX()) + .query(builtQuery.boolQuery.build()._toQuery()); + CountResponse response = client.count(countBuilder.build()); + + return response.count(); + } catch (Exception e) { + 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); } - - - - @Override - public void deleteAllById(Iterable ids) { - // TODO Auto-generated method stub - - } - + } + + /** + * Match count + * + * @param propertyName channel search property name + * @param propertyValue channel search property value + * @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); + } + + /** + * Match count + * + * @param tagName channel search tag + * @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); + } + + @Override + public void deleteAllById(Iterable ids) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/org/phoebus/channelfinder/ChannelScroll.java b/src/main/java/org/phoebus/channelfinder/ChannelScroll.java index 03e56f6c..5ac61755 100644 --- a/src/main/java/org/phoebus/channelfinder/ChannelScroll.java +++ b/src/main/java/org/phoebus/channelfinder/ChannelScroll.java @@ -2,12 +2,20 @@ import static org.phoebus.channelfinder.CFResourceDescriptors.SCROLL_RESOURCE_URI; +import co.elastic.clients.elasticsearch.ElasticsearchClient; +import co.elastic.clients.elasticsearch._types.FieldSort; +import co.elastic.clients.elasticsearch._types.FieldValue; +import co.elastic.clients.elasticsearch._types.SortOptions; +import co.elastic.clients.elasticsearch._types.query_dsl.*; +import co.elastic.clients.elasticsearch.core.SearchRequest; +import co.elastic.clients.elasticsearch.core.SearchResponse; +import co.elastic.clients.elasticsearch.core.search.Hit; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import java.text.MessageFormat; import java.util.Comparator; import java.util.List; @@ -16,14 +24,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; - -import co.elastic.clients.elasticsearch._types.FieldSort; -import co.elastic.clients.elasticsearch._types.FieldValue; -import co.elastic.clients.elasticsearch._types.SortOptions; -import co.elastic.clients.elasticsearch._types.query_dsl.*; -import co.elastic.clients.elasticsearch.core.SearchRequest; -import co.elastic.clients.elasticsearch.core.SearchResponse; -import co.elastic.clients.elasticsearch.core.search.Hit; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Scroll; import org.springframework.beans.factory.annotation.Autowired; @@ -37,8 +37,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; - -import co.elastic.clients.elasticsearch.ElasticsearchClient; import org.springframework.web.server.ResponseStatusException; @CrossOrigin @@ -47,170 +45,198 @@ @EnableAutoConfiguration public class ChannelScroll { - private static final Logger logger = Logger.getLogger(ChannelScroll.class.getName()); + private static final Logger logger = Logger.getLogger(ChannelScroll.class.getName()); - @Autowired - ElasticConfig esService; + @Autowired ElasticConfig esService; - @Autowired - @Qualifier("indexClient") - ElasticsearchClient client; + @Autowired + @Qualifier("indexClient") + ElasticsearchClient client; - @Operation( - summary = "Scroll query for channels", - description = "Retrieve a collection of Channel instances based on multi-parameter search.", - operationId = "scrollQueryChannels", - tags = {"ChannelScroll"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Scroll that contains a collection of channel instances", - content = @Content(schema = @Schema(implementation = Scroll.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to list channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping - public Scroll query( - @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap allRequestParams) { - return search(null, allRequestParams); - } + @Operation( + summary = "Scroll query for channels", + description = "Retrieve a collection of Channel instances based on multi-parameter search.", + operationId = "scrollQueryChannels", + tags = {"ChannelScroll"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Scroll that contains a collection of channel instances", + content = @Content(schema = @Schema(implementation = Scroll.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to list channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping + public Scroll query( + @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap allRequestParams) { + return search(null, allRequestParams); + } - @Operation( - summary = "Scroll query by scrollId", - description = "Retrieve a collection of Channel instances using a scrollId and search parameters.", - operationId = "scrollQueryById", - tags = {"ChannelScroll"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Scroll List of channels", - content = @Content(schema = @Schema(implementation = Scroll.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to list channels", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/{scrollId}") - public Scroll query( - @Parameter(description = "Scroll ID from previous query") @PathVariable("scrollId") String scrollId, - @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap searchParameters) { - return search(scrollId, searchParameters); - } + @Operation( + summary = "Scroll query by scrollId", + description = + "Retrieve a collection of Channel instances using a scrollId and search parameters.", + operationId = "scrollQueryById", + tags = {"ChannelScroll"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Scroll List of channels", + content = @Content(schema = @Schema(implementation = Scroll.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to list channels", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/{scrollId}") + public Scroll query( + @Parameter(description = "Scroll ID from previous query") @PathVariable("scrollId") + String scrollId, + @Parameter(description = CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap searchParameters) { + return search(scrollId, searchParameters); + } - /** - * Search for a list of channels based on their name, tags, and/or properties. - * Search parameters ~name - The name of the channel ~tags - A list of comma - * separated values ${propertyName}:${propertyValue} - - *

- * The query result is sorted based on the channel name ~size - The number of - * channels to be returned ~from - The starting index of the channel list - * - * TODO combine with ChannelRepository code. - * @param scrollId scroll ID - * @param searchParameters - search parameters for scrolling searches - * @return search scroll - */ - public Scroll search(String scrollId, MultiValueMap searchParameters) { - BoolQuery.Builder boolQuery = new BoolQuery.Builder(); - int size = esService.getES_QUERY_SIZE(); - int from = 0; + /** + * Search for a list of channels based on their name, tags, and/or properties. Search parameters + * ~name - The name of the channel ~tags - A list of comma separated values + * ${propertyName}:${propertyValue} - + * + *

The query result is sorted based on the channel name ~size - The number of channels to be + * returned ~from - The starting index of the channel list + * + *

TODO combine with ChannelRepository code. + * + * @param scrollId scroll ID + * @param searchParameters - search parameters for scrolling searches + * @return search scroll + */ + public Scroll search(String scrollId, MultiValueMap searchParameters) { + BoolQuery.Builder boolQuery = new BoolQuery.Builder(); + int size = esService.getES_QUERY_SIZE(); + int from = 0; - for (Map.Entry> parameter : searchParameters.entrySet()) { - String key = parameter.getKey().trim(); - boolean isNot = key.endsWith("!"); + for (Map.Entry> parameter : searchParameters.entrySet()) { + String key = parameter.getKey().trim(); + boolean isNot = key.endsWith("!"); + if (isNot) { + key = key.substring(0, key.length() - 1); + } + switch (key) { + case "~name": + for (String value : parameter.getValue()) { + DisMaxQuery.Builder nameQuery = new DisMaxQuery.Builder(); + for (String pattern : value.split("[\\|,;]")) { + nameQuery.queries( + WildcardQuery.of(w -> w.field("name").value(pattern.trim()))._toQuery()); + } + boolQuery.must(nameQuery.build()._toQuery()); + } + break; + case "~tag": + for (String value : parameter.getValue()) { + DisMaxQuery.Builder tagQuery = new DisMaxQuery.Builder(); + for (String pattern : value.split("[\\|,;]")) { + tagQuery.queries( + NestedQuery.of( + n -> + n.path("tags") + .query( + WildcardQuery.of( + w -> w.field("tags.name").value(pattern.trim())) + ._toQuery())) + ._toQuery()); + } if (isNot) { - key = key.substring(0, key.length() - 1); + boolQuery.mustNot(tagQuery.build()._toQuery()); + } else { + boolQuery.must(tagQuery.build()._toQuery()); } - switch (key) { - case "~name": - for (String value : parameter.getValue()) { - DisMaxQuery.Builder nameQuery = new DisMaxQuery.Builder(); - for (String pattern : value.split("[\\|,;]")) { - nameQuery.queries(WildcardQuery.of(w -> w.field("name").value(pattern.trim()))._toQuery()); - } - boolQuery.must(nameQuery.build()._toQuery()); - } - break; - case "~tag": - for (String value : parameter.getValue()) { - DisMaxQuery.Builder tagQuery = new DisMaxQuery.Builder(); - for (String pattern : value.split("[\\|,;]")) { - tagQuery.queries( - NestedQuery.of(n -> n.path("tags").query( - WildcardQuery.of(w -> w.field("tags.name").value(pattern.trim()))._toQuery()))._toQuery()); - } - if (isNot) { - boolQuery.mustNot(tagQuery.build()._toQuery()); - } else { - boolQuery.must(tagQuery.build()._toQuery()); - } + } + break; + case "~size": + Optional maxSize = + parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); + if (maxSize.isPresent()) { + size = Integer.parseInt(maxSize.get()); + } + break; + case "~from": + Optional maxFrom = + parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); + if (maxFrom.isPresent()) { + from = Integer.parseInt(maxFrom.get()); + } + break; - } - break; - case "~size": - Optional maxSize = parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); - if (maxSize.isPresent()) { - size = Integer.parseInt(maxSize.get()); - } - break; - case "~from": - Optional maxFrom = parameter.getValue().stream().max(Comparator.comparing(Integer::valueOf)); - if (maxFrom.isPresent()) { - from = Integer.parseInt(maxFrom.get()); - } - break; - - default: - DisMaxQuery.Builder propertyQuery = new DisMaxQuery.Builder(); - for (String value : parameter.getValue()) { - for (String pattern : value.split("[\\|,;]")) { - String finalKey = key; - BoolQuery bq; - if (isNot) { - bq = BoolQuery.of(p -> p.must(MatchQuery.of(name -> name.field("properties.name").query(finalKey))._toQuery()) - .mustNot(WildcardQuery.of(val -> val.field("properties.value").value(pattern.trim()))._toQuery())); - } else { - bq = BoolQuery.of(p -> p.must(MatchQuery.of(name -> name.field("properties.name").query(finalKey))._toQuery()) - .must(WildcardQuery.of(val -> val.field("properties.value").value(pattern.trim()))._toQuery())); - } - propertyQuery.queries( - NestedQuery.of(n -> n.path("properties").query(bq._toQuery()))._toQuery() - ); - } - } - boolQuery.must(propertyQuery.build()._toQuery()); - break; + default: + DisMaxQuery.Builder propertyQuery = new DisMaxQuery.Builder(); + for (String value : parameter.getValue()) { + for (String pattern : value.split("[\\|,;]")) { + String finalKey = key; + BoolQuery bq; + if (isNot) { + bq = + BoolQuery.of( + p -> + p.must( + MatchQuery.of( + name -> name.field("properties.name").query(finalKey)) + ._toQuery()) + .mustNot( + WildcardQuery.of( + val -> + val.field("properties.value").value(pattern.trim())) + ._toQuery())); + } else { + bq = + BoolQuery.of( + p -> + p.must( + MatchQuery.of( + name -> name.field("properties.name").query(finalKey)) + ._toQuery()) + .must( + WildcardQuery.of( + val -> + val.field("properties.value").value(pattern.trim())) + ._toQuery())); + } + propertyQuery.queries( + NestedQuery.of(n -> n.path("properties").query(bq._toQuery()))._toQuery()); } - } + } + boolQuery.must(propertyQuery.build()._toQuery()); + break; + } + } - try { - SearchRequest.Builder builder = new SearchRequest.Builder(); - builder.index(esService.getES_CHANNEL_INDEX()) - .query(boolQuery.build()._toQuery()) - .from(from) - .size(size) - .sort(SortOptions.of(o -> o.field(FieldSort.of(f -> f.field("name"))))); - if(scrollId != null && !scrollId.isEmpty()) { - builder.searchAfter(FieldValue.of(scrollId)); - } - SearchResponse response = client.search(builder.build(), - Channel.class - ); - List> hits = response.hits().hits(); - return new Scroll(!hits.isEmpty() ? hits.get(hits.size()-1).id() : null, hits.stream().map(Hit::source).collect(Collectors.toList())); - } catch (Exception e) { - 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); - } + try { + SearchRequest.Builder builder = new SearchRequest.Builder(); + builder + .index(esService.getES_CHANNEL_INDEX()) + .query(boolQuery.build()._toQuery()) + .from(from) + .size(size) + .sort(SortOptions.of(o -> o.field(FieldSort.of(f -> f.field("name"))))); + if (scrollId != null && !scrollId.isEmpty()) { + builder.searchAfter(FieldValue.of(scrollId)); + } + SearchResponse response = client.search(builder.build(), Channel.class); + List> hits = response.hits().hits(); + return new Scroll( + !hits.isEmpty() ? hits.get(hits.size() - 1).id() : null, + hits.stream().map(Hit::source).collect(Collectors.toList())); + } catch (Exception e) { + 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); } - + } } diff --git a/src/main/java/org/phoebus/channelfinder/ElasticConfig.java b/src/main/java/org/phoebus/channelfinder/ElasticConfig.java index e8686c66..7d0943bb 100644 --- a/src/main/java/org/phoebus/channelfinder/ElasticConfig.java +++ b/src/main/java/org/phoebus/channelfinder/ElasticConfig.java @@ -1,6 +1,4 @@ -/** - * - */ +/** */ package org.phoebus.channelfinder; /* @@ -14,33 +12,32 @@ * #L% */ -import java.io.IOException; -import java.io.InputStream; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - +import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.indices.CreateIndexRequest; import co.elastic.clients.elasticsearch.indices.CreateIndexResponse; import co.elastic.clients.elasticsearch.indices.ExistsRequest; import co.elastic.clients.elasticsearch.indices.IndexSettings; import co.elastic.clients.elasticsearch.indices.PutIndicesSettingsRequest; import co.elastic.clients.elasticsearch.indices.PutIndicesSettingsResponse; +import co.elastic.clients.json.jackson.JacksonJsonpMapper; +import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.endpoints.BooleanResponse; +import co.elastic.clients.transport.rest_client.RestClientTransport; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; import org.apache.http.message.BasicHeader; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; @@ -53,176 +50,220 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import co.elastic.clients.elasticsearch.ElasticsearchClient; -import co.elastic.clients.json.jackson.JacksonJsonpMapper; -import co.elastic.clients.transport.ElasticsearchTransport; -import co.elastic.clients.transport.rest_client.RestClientTransport; - /** * @author Kunal Shroff {@literal } - * */ - @Configuration @ConfigurationProperties(prefix = "elasticsearch") -@ComponentScan(basePackages = { "org.phoebus.channelfinder" }) +@ComponentScan(basePackages = {"org.phoebus.channelfinder"}) @PropertySource(value = "classpath:application.properties") public class ElasticConfig implements ServletContextListener { - private static final Logger logger = Logger.getLogger(ElasticConfig.class.getName()); - - private ElasticsearchClient searchClient; - private ElasticsearchClient indexClient; - - @Value("${elasticsearch.network.host:localhost}") - private String host; - @Value("${elasticsearch.host_urls:http://localhost:9200}") - private String[] httpHostUrls; - @Value("${elasticsearch.http.port:9200}") - private int port; - @Value("${elasticsearch.authorization.header:}") - private String authorizationHeader; - @Value("${elasticsearch.authorization.username:}") - private String username; - @Value("${elasticsearch.authorization.password:}") - private String password; - @Value("${elasticsearch.create.indices:true}") - private String createIndices; - - @Value("${elasticsearch.tag.index:cf_tags}") - private String ES_TAG_INDEX; - @Value("${elasticsearch.property.index:cf_properties}") - private String ES_PROPERTY_INDEX; - @Value("${elasticsearch.channel.index:channelfinder}") - private String ES_CHANNEL_INDEX; - @Value("${elasticsearch.query.size:10000}") - private int ES_QUERY_SIZE; - - public String getES_TAG_INDEX() { - return this.ES_TAG_INDEX; - } - public String getES_PROPERTY_INDEX() { - return this.ES_PROPERTY_INDEX; - } - public String getES_CHANNEL_INDEX() { - return this.ES_CHANNEL_INDEX; - } - public int getES_QUERY_SIZE() { - return this.ES_QUERY_SIZE; - } - public int getES_MAX_RESULT_WINDOW_SIZE() { - return ES_QUERY_SIZE; - } + private static final Logger logger = Logger.getLogger(ElasticConfig.class.getName()); - ObjectMapper objectMapper = new ObjectMapper() - .addMixIn(Tag.class, Tag.OnlyTag.class) - .addMixIn(Property.class, Property.OnlyProperty.class); - - private static ElasticsearchClient createClient(ElasticsearchClient currentClient, ObjectMapper objectMapper, - HttpHost[] httpHosts, String createIndices, ElasticConfig config) { - ElasticsearchClient client; - if (currentClient == null) { - // Create the low-level client - RestClientBuilder clientBuilder = RestClient.builder(httpHosts); - // Configure authentication - if (!config.authorizationHeader.isEmpty()) { - clientBuilder.setDefaultHeaders(new Header[] {new BasicHeader("Authorization", config.authorizationHeader)}); - if (!config.username.isEmpty() || !config.password.isEmpty()) { - logger.warning("elasticsearch.authorization_header is set, ignoring elasticsearch.username and elasticsearch.password."); - } - } else if (!config.username.isEmpty() || !config.password.isEmpty()) { - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(config.username, config.password)); - clientBuilder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); - } - RestClient httpClient = clientBuilder.build(); - - // Create the Java API Client with the same low level client - ElasticsearchTransport transport = new RestClientTransport(httpClient, new JacksonJsonpMapper(objectMapper)); - - client = new ElasticsearchClient(transport); - } else { - client = currentClient; - } - if (Boolean.parseBoolean(createIndices)) { - config.elasticIndexValidation(client); - } - return client; + private ElasticsearchClient searchClient; + private ElasticsearchClient indexClient; - } + @Value("${elasticsearch.network.host:localhost}") + private String host; + + @Value("${elasticsearch.host_urls:http://localhost:9200}") + private String[] httpHostUrls; + + @Value("${elasticsearch.http.port:9200}") + private int port; + + @Value("${elasticsearch.authorization.header:}") + private String authorizationHeader; + + @Value("${elasticsearch.authorization.username:}") + private String username; + + @Value("${elasticsearch.authorization.password:}") + private String password; + + @Value("${elasticsearch.create.indices:true}") + private String createIndices; + + @Value("${elasticsearch.tag.index:cf_tags}") + private String ES_TAG_INDEX; + + @Value("${elasticsearch.property.index:cf_properties}") + private String ES_PROPERTY_INDEX; + + @Value("${elasticsearch.channel.index:channelfinder}") + private String ES_CHANNEL_INDEX; + + @Value("${elasticsearch.query.size:10000}") + private int ES_QUERY_SIZE; - private HttpHost[] getHttpHosts() { - boolean hostIsDefault = host.equals("localhost"); - boolean hostUrlsIsDefault = httpHostUrls.length == 1 && httpHostUrls[0].equals("http://localhost:9200"); - boolean portIsDefault = (port == 9200); - if (hostUrlsIsDefault && (!hostIsDefault || !portIsDefault)) { - logger.warning("Specifying elasticsearch.network.host and elasticsearch.http.port is deprecated, please consider using elasticsearch.host_urls instead."); - return new HttpHost[] {new HttpHost(host, port)}; - } else { - if (!hostIsDefault) { - logger.warning("Only one of elasticsearch.host_urls and elasticsearch.network.host can be set, ignoring elasticsearch.network.host."); - } - if (!portIsDefault) { - logger.warning("Only one of elasticsearch.host_urls and elasticsearch.http.port can be set, ignoring elasticsearch.http.port."); - } - return Arrays.stream(httpHostUrls).map(HttpHost::create).toArray(HttpHost[]::new); + public String getES_TAG_INDEX() { + return this.ES_TAG_INDEX; + } + + public String getES_PROPERTY_INDEX() { + return this.ES_PROPERTY_INDEX; + } + + public String getES_CHANNEL_INDEX() { + return this.ES_CHANNEL_INDEX; + } + + public int getES_QUERY_SIZE() { + return this.ES_QUERY_SIZE; + } + + public int getES_MAX_RESULT_WINDOW_SIZE() { + return ES_QUERY_SIZE; + } + + ObjectMapper objectMapper = + new ObjectMapper() + .addMixIn(Tag.class, Tag.OnlyTag.class) + .addMixIn(Property.class, Property.OnlyProperty.class); + + private static ElasticsearchClient createClient( + ElasticsearchClient currentClient, + ObjectMapper objectMapper, + HttpHost[] httpHosts, + String createIndices, + ElasticConfig config) { + ElasticsearchClient client; + if (currentClient == null) { + // Create the low-level client + RestClientBuilder clientBuilder = RestClient.builder(httpHosts); + // Configure authentication + if (!config.authorizationHeader.isEmpty()) { + clientBuilder.setDefaultHeaders( + new Header[] {new BasicHeader("Authorization", config.authorizationHeader)}); + if (!config.username.isEmpty() || !config.password.isEmpty()) { + logger.warning( + "elasticsearch.authorization_header is set, ignoring elasticsearch.username and elasticsearch.password."); } - } + } else if (!config.username.isEmpty() || !config.password.isEmpty()) { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials( + AuthScope.ANY, new UsernamePasswordCredentials(config.username, config.password)); + clientBuilder.setHttpClientConfigCallback( + httpClientBuilder -> + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); + } + RestClient httpClient = clientBuilder.build(); - @Bean({ "searchClient" }) - public ElasticsearchClient getSearchClient() { - searchClient = createClient(searchClient, objectMapper, getHttpHosts(), createIndices, this); - return searchClient; - } + // Create the Java API Client with the same low level client + ElasticsearchTransport transport = + new RestClientTransport(httpClient, new JacksonJsonpMapper(objectMapper)); - @Bean({ "indexClient" }) - public ElasticsearchClient getIndexClient() { - indexClient = createClient(indexClient, objectMapper, getHttpHosts(), createIndices, this); - return indexClient; + client = new ElasticsearchClient(transport); + } else { + client = currentClient; } - - @Override - public void contextInitialized(ServletContextEvent sce) { - logger.log(Level.INFO, "Initializing a new Transport clients."); + if (Boolean.parseBoolean(createIndices)) { + config.elasticIndexValidation(client); } + return client; + } - @Override - public void contextDestroyed(ServletContextEvent sce) { - logger.log(Level.INFO, "Closing the default Transport clients."); - if (searchClient != null) - searchClient.shutdown(); - if (indexClient != null) - indexClient.shutdown(); + private HttpHost[] getHttpHosts() { + boolean hostIsDefault = host.equals("localhost"); + boolean hostUrlsIsDefault = + httpHostUrls.length == 1 && httpHostUrls[0].equals("http://localhost:9200"); + boolean portIsDefault = (port == 9200); + if (hostUrlsIsDefault && (!hostIsDefault || !portIsDefault)) { + logger.warning( + "Specifying elasticsearch.network.host and elasticsearch.http.port is deprecated, please consider using elasticsearch.host_urls instead."); + return new HttpHost[] {new HttpHost(host, port)}; + } else { + if (!hostIsDefault) { + logger.warning( + "Only one of elasticsearch.host_urls and elasticsearch.network.host can be set, ignoring elasticsearch.network.host."); + } + if (!portIsDefault) { + logger.warning( + "Only one of elasticsearch.host_urls and elasticsearch.http.port can be set, ignoring elasticsearch.http.port."); + } + return Arrays.stream(httpHostUrls).map(HttpHost::create).toArray(HttpHost[]::new); } + } - /** - * Create the olog indices and templates if they don't exist - * @param client client connected to elasticsearch - */ - void elasticIndexValidation(ElasticsearchClient client) { - validateIndex(client, ES_CHANNEL_INDEX, "/channel_mapping.json"); - validateIndex(client, ES_TAG_INDEX, "/tag_mapping.json"); - validateIndex(client, ES_PROPERTY_INDEX, "/properties_mapping.json"); - } + @Bean({"searchClient"}) + public ElasticsearchClient getSearchClient() { + searchClient = createClient(searchClient, objectMapper, getHttpHosts(), createIndices, this); + return searchClient; + } - private void validateIndex(ElasticsearchClient client, String esIndex, String mapping) { - - // ChannelFinder Index - try (InputStream is = ElasticConfig.class.getResourceAsStream(mapping)) { - BooleanResponse exits = client.indices().exists(ExistsRequest.of(e -> e.index(esIndex))); - if(!exits.value()) { - CreateIndexResponse result = client.indices().create( - CreateIndexRequest.of( - c -> c.index(esIndex) - .withJson(is) - .settings(IndexSettings.of(builder -> builder.maxResultWindow(getES_MAX_RESULT_WINDOW_SIZE()))))); - logger.log(Level.INFO, () -> MessageFormat.format(TextUtil.CREATED_INDEX_ACKNOWLEDGED, esIndex, result.acknowledged())); - } - PutIndicesSettingsResponse response = client.indices() - .putSettings(PutIndicesSettingsRequest.of(builder -> builder.index(esIndex).settings(IndexSettings.of(i -> i.maxResultWindow(getES_MAX_RESULT_WINDOW_SIZE()))))); - logger.log(Level.INFO, () -> MessageFormat.format(TextUtil.UPDATE_INDEX_ACKNOWLEDGED, esIndex, response.acknowledged())); - } catch (IOException e) { - logger.log(Level.WARNING, MessageFormat.format(TextUtil.FAILED_TO_CREATE_INDEX, esIndex), e); - } + @Bean({"indexClient"}) + public ElasticsearchClient getIndexClient() { + indexClient = createClient(indexClient, objectMapper, getHttpHosts(), createIndices, this); + return indexClient; + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + logger.log(Level.INFO, "Initializing a new Transport clients."); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + logger.log(Level.INFO, "Closing the default Transport clients."); + if (searchClient != null) searchClient.shutdown(); + if (indexClient != null) indexClient.shutdown(); + } + + /** + * Create the olog indices and templates if they don't exist + * + * @param client client connected to elasticsearch + */ + void elasticIndexValidation(ElasticsearchClient client) { + validateIndex(client, ES_CHANNEL_INDEX, "/channel_mapping.json"); + validateIndex(client, ES_TAG_INDEX, "/tag_mapping.json"); + validateIndex(client, ES_PROPERTY_INDEX, "/properties_mapping.json"); + } + + private void validateIndex(ElasticsearchClient client, String esIndex, String mapping) { + + // ChannelFinder Index + try (InputStream is = ElasticConfig.class.getResourceAsStream(mapping)) { + BooleanResponse exits = client.indices().exists(ExistsRequest.of(e -> e.index(esIndex))); + if (!exits.value()) { + CreateIndexResponse result = + client + .indices() + .create( + CreateIndexRequest.of( + c -> + c.index(esIndex) + .withJson(is) + .settings( + IndexSettings.of( + builder -> + builder.maxResultWindow( + getES_MAX_RESULT_WINDOW_SIZE()))))); + logger.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CREATED_INDEX_ACKNOWLEDGED, esIndex, result.acknowledged())); + } + PutIndicesSettingsResponse response = + client + .indices() + .putSettings( + PutIndicesSettingsRequest.of( + builder -> + builder + .index(esIndex) + .settings( + IndexSettings.of( + i -> i.maxResultWindow(getES_MAX_RESULT_WINDOW_SIZE()))))); + logger.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.UPDATE_INDEX_ACKNOWLEDGED, esIndex, response.acknowledged())); + } catch (IOException e) { + logger.log(Level.WARNING, MessageFormat.format(TextUtil.FAILED_TO_CREATE_INDEX, esIndex), e); } + } } diff --git a/src/main/java/org/phoebus/channelfinder/HttpConnectorConfig.java b/src/main/java/org/phoebus/channelfinder/HttpConnectorConfig.java index 1b61e90a..fe44408f 100644 --- a/src/main/java/org/phoebus/channelfinder/HttpConnectorConfig.java +++ b/src/main/java/org/phoebus/channelfinder/HttpConnectorConfig.java @@ -13,23 +13,24 @@ @PropertySource(value = "classpath:application.properties") public class HttpConnectorConfig { - @Value("${server.http.enable:true}") - private boolean httpEnabled; - @Value("${server.http.port:8080}") - private int port; + @Value("${server.http.enable:true}") + private boolean httpEnabled; - @Bean - @ConditionalOnProperty(name="server.http.enable") - public ServletWebServerFactory servletContainer() { - TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); - tomcat.addAdditionalTomcatConnectors(getHttpConnector()); - return tomcat; - } + @Value("${server.http.port:8080}") + private int port; - private Connector getHttpConnector() { - Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); - connector.setScheme("http"); - connector.setPort(port); - return connector; - } -} \ No newline at end of file + @Bean + @ConditionalOnProperty(name = "server.http.enable") + public ServletWebServerFactory servletContainer() { + TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); + tomcat.addAdditionalTomcatConnectors(getHttpConnector()); + return tomcat; + } + + private Connector getHttpConnector() { + Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); + connector.setScheme("http"); + connector.setPort(port); + return connector; + } +} diff --git a/src/main/java/org/phoebus/channelfinder/InfoManager.java b/src/main/java/org/phoebus/channelfinder/InfoManager.java index 1515b5d0..1c4f2c99 100644 --- a/src/main/java/org/phoebus/channelfinder/InfoManager.java +++ b/src/main/java/org/phoebus/channelfinder/InfoManager.java @@ -2,16 +2,21 @@ import static org.phoebus.channelfinder.CFResourceDescriptors.CF_SERVICE_INFO; +import co.elastic.clients.elasticsearch.ElasticsearchClient; +import co.elastic.clients.elasticsearch._types.ElasticsearchVersionInfo; +import co.elastic.clients.elasticsearch.core.InfoResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import java.util.logging.Level; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -20,68 +25,63 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -import co.elastic.clients.elasticsearch.ElasticsearchClient; -import co.elastic.clients.elasticsearch._types.ElasticsearchVersionInfo; -import co.elastic.clients.elasticsearch.core.InfoResponse; - @CrossOrigin @RestController @RequestMapping(CF_SERVICE_INFO) @EnableAutoConfiguration public class InfoManager { - @Value("${channelfinder.version:4.7.0}") - private String version; - - @Autowired - private ElasticConfig esService; + @Value("${channelfinder.version:4.7.0}") + private String version; + + @Autowired private ElasticConfig esService; - private static final ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + private static final ObjectMapper objectMapper = + new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); - @Operation( - summary = "Get ChannelFinder service info", - description = "Returns information about the ChannelFinder service and its Elasticsearch backend.", - operationId = "getServiceInfo", - tags = {"Info"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "ChannelFinder info", content = @Content(schema = @Schema(implementation = String.class))) - }) - @GetMapping - public String info() { + @Operation( + summary = "Get ChannelFinder service info", + description = + "Returns information about the ChannelFinder service and its Elasticsearch backend.", + operationId = "getServiceInfo", + tags = {"Info"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "ChannelFinder info", + content = @Content(schema = @Schema(implementation = String.class))) + }) + @GetMapping + public String info() { - Map cfServiceInfo = new LinkedHashMap<>(); - cfServiceInfo.put("name", "ChannelFinder Service"); - cfServiceInfo.put("version", version); + Map cfServiceInfo = new LinkedHashMap<>(); + cfServiceInfo.put("name", "ChannelFinder Service"); + cfServiceInfo.put("version", version); - Map elasticInfo = new LinkedHashMap<>(); - try { + Map elasticInfo = new LinkedHashMap<>(); + try { - ElasticsearchClient client = esService.getSearchClient(); - InfoResponse response = client.info(); - - elasticInfo.put("status", "Connected"); - elasticInfo.put("clusterName", response.clusterName()); - elasticInfo.put("clusterUuid", response.clusterUuid()); - ElasticsearchVersionInfo elasticVersion = response.version(); - elasticInfo.put("version", elasticVersion.number()); - } catch (IOException e) { - Application.logger.log(Level.WARNING, "Failed to create ChannelFinder service info resource.", e); - elasticInfo.put("status", "Failed to connect to elastic " + e.getLocalizedMessage()); - } - cfServiceInfo.put("elastic", elasticInfo); - try { - return objectMapper.writeValueAsString(cfServiceInfo); - } catch (JsonProcessingException e) { - Application.logger.log(Level.WARNING, "Failed to create ChannelFinder service info resource.", e); - return "Failed to gather ChannelFinder service info"; - } + ElasticsearchClient client = esService.getSearchClient(); + InfoResponse response = client.info(); + + elasticInfo.put("status", "Connected"); + elasticInfo.put("clusterName", response.clusterName()); + elasticInfo.put("clusterUuid", response.clusterUuid()); + ElasticsearchVersionInfo elasticVersion = response.version(); + elasticInfo.put("version", elasticVersion.number()); + } catch (IOException e) { + Application.logger.log( + Level.WARNING, "Failed to create ChannelFinder service info resource.", e); + elasticInfo.put("status", "Failed to connect to elastic " + e.getLocalizedMessage()); + } + cfServiceInfo.put("elastic", elasticInfo); + try { + return objectMapper.writeValueAsString(cfServiceInfo); + } catch (JsonProcessingException e) { + Application.logger.log( + Level.WARNING, "Failed to create ChannelFinder service info resource.", e); + return "Failed to gather ChannelFinder service info"; } + } } diff --git a/src/main/java/org/phoebus/channelfinder/MetricsService.java b/src/main/java/org/phoebus/channelfinder/MetricsService.java index ff31e16b..78db0e8e 100644 --- a/src/main/java/org/phoebus/channelfinder/MetricsService.java +++ b/src/main/java/org/phoebus/channelfinder/MetricsService.java @@ -4,199 +4,211 @@ import io.micrometer.core.instrument.ImmutableTag; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.PropertySource; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; -import java.util.Map.Entry; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; @Service @PropertySource(value = "classpath:application.properties") public class MetricsService { - public static final String CF_TOTAL_CHANNEL_COUNT = "cf.total.channel.count"; - public static final String CF_PROPERTY_COUNT = "cf.property.count"; - public static final String CF_TAG_COUNT = "cf.tag.count"; - public static final String CF_CHANNEL_COUNT = "cf.channel.count"; - public static final String CF_TAG_ON_CHANNELS_COUNT = "cf.tag_on_channels.count"; - private static final String METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT = "Count of all ChannelFinder channels"; - private static final String METRIC_DESCRIPTION_PROPERTY_COUNT = "Count of all ChannelFinder properties"; - private static final String METRIC_DESCRIPTION_TAG_COUNT = "Count of all ChannelFinder tags"; - private static final String METRIC_DESCRIPTION_CHANNEL_COUNT = "Count of all ChannelFinder channels with set properties"; - private static final String BASE_UNIT = "channels"; - private static final String NEGATE = "!"; - public static final String NOT_SET = "-"; - - private final ChannelRepository channelRepository; - private final PropertyRepository propertyRepository; - private final TagRepository tagRepository; - private final MeterRegistry meterRegistry; - - private Map, AtomicLong> propertyMetrics; - private Map tagMetrics; - - @Value("${metrics.tags}") - private String[] tags; - - @Value("${metrics.properties}") - private String metricProperties; - - Map> parseProperties() { - if (metricProperties == null || metricProperties.isEmpty()) { - return new LinkedMultiValueMap<>(); - } - return Arrays.stream(metricProperties.split(";")).map(s -> - { - String[] split = s.split(":"); - String k = split[0].trim(); - List v = Arrays.stream(split[1].split(",")).map(String::trim).toList(); - return Map.entry(k, v); - }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + public static final String CF_TOTAL_CHANNEL_COUNT = "cf.total.channel.count"; + public static final String CF_PROPERTY_COUNT = "cf.property.count"; + public static final String CF_TAG_COUNT = "cf.tag.count"; + public static final String CF_CHANNEL_COUNT = "cf.channel.count"; + public static final String CF_TAG_ON_CHANNELS_COUNT = "cf.tag_on_channels.count"; + private static final String METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT = + "Count of all ChannelFinder channels"; + private static final String METRIC_DESCRIPTION_PROPERTY_COUNT = + "Count of all ChannelFinder properties"; + private static final String METRIC_DESCRIPTION_TAG_COUNT = "Count of all ChannelFinder tags"; + private static final String METRIC_DESCRIPTION_CHANNEL_COUNT = + "Count of all ChannelFinder channels with set properties"; + private static final String BASE_UNIT = "channels"; + private static final String NEGATE = "!"; + public static final String NOT_SET = "-"; + + private final ChannelRepository channelRepository; + private final PropertyRepository propertyRepository; + private final TagRepository tagRepository; + private final MeterRegistry meterRegistry; + + private Map, AtomicLong> propertyMetrics; + private Map tagMetrics; + + @Value("${metrics.tags}") + private String[] tags; + + @Value("${metrics.properties}") + private String metricProperties; + + Map> parseProperties() { + if (metricProperties == null || metricProperties.isEmpty()) { + return new LinkedMultiValueMap<>(); } - - @Autowired - public MetricsService( - final ChannelRepository channelRepository, - final PropertyRepository propertyRepository, - final TagRepository tagRepository, - final MeterRegistry meterRegistry) { - this.channelRepository = channelRepository; - this.propertyRepository = propertyRepository; - this.tagRepository = tagRepository; - this.meterRegistry = meterRegistry; - } - - @PostConstruct - private void registerGaugeMetrics() { - Gauge.builder(CF_TOTAL_CHANNEL_COUNT, () -> channelRepository.count(new LinkedMultiValueMap<>())) - .description(METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT) - .register(meterRegistry); - Gauge.builder(CF_PROPERTY_COUNT, propertyRepository::count) - .description(METRIC_DESCRIPTION_PROPERTY_COUNT) - .register(meterRegistry); - Gauge.builder(CF_TAG_COUNT, tagRepository::count) - .description(METRIC_DESCRIPTION_TAG_COUNT) - .register(meterRegistry); - registerTagMetrics(); - registerPropertyMetrics(); - } - - - private void registerTagMetrics() { - // Add tags - tagMetrics = Arrays.stream(tags) + return Arrays.stream(metricProperties.split(";")) + .map( + s -> { + String[] split = s.split(":"); + String k = split[0].trim(); + List v = Arrays.stream(split[1].split(",")).map(String::trim).toList(); + return Map.entry(k, v); + }) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + @Autowired + public MetricsService( + final ChannelRepository channelRepository, + final PropertyRepository propertyRepository, + final TagRepository tagRepository, + final MeterRegistry meterRegistry) { + this.channelRepository = channelRepository; + this.propertyRepository = propertyRepository; + this.tagRepository = tagRepository; + this.meterRegistry = meterRegistry; + } + + @PostConstruct + private void registerGaugeMetrics() { + Gauge.builder( + CF_TOTAL_CHANNEL_COUNT, () -> channelRepository.count(new LinkedMultiValueMap<>())) + .description(METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT) + .register(meterRegistry); + Gauge.builder(CF_PROPERTY_COUNT, propertyRepository::count) + .description(METRIC_DESCRIPTION_PROPERTY_COUNT) + .register(meterRegistry); + Gauge.builder(CF_TAG_COUNT, tagRepository::count) + .description(METRIC_DESCRIPTION_TAG_COUNT) + .register(meterRegistry); + registerTagMetrics(); + registerPropertyMetrics(); + } + + private void registerTagMetrics() { + // Add tags + tagMetrics = + Arrays.stream(tags) .map(t -> Map.entry(t, new AtomicLong(0))) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - for (String tag : tags) { - Gauge.builder(CF_TAG_ON_CHANNELS_COUNT, tagMetrics, m -> m.get(tag).doubleValue()) - .description("Number of channels with tag") - .tag("tag", tag) - .baseUnit(BASE_UNIT) - .register(meterRegistry); - } + for (String tag : tags) { + Gauge.builder(CF_TAG_ON_CHANNELS_COUNT, tagMetrics, m -> m.get(tag).doubleValue()) + .description("Number of channels with tag") + .tag("tag", tag) + .baseUnit(BASE_UNIT) + .register(meterRegistry); } + } - public static List> generateAllMultiValueMaps(Map> properties) { - List> allMultiValueMaps = new ArrayList<>(); - - if (properties.isEmpty()) { - allMultiValueMaps.add(new LinkedMultiValueMap<>()); // Add an empty map for the case where all are null - return allMultiValueMaps; - } - - List>> entries = new ArrayList<>(properties.entrySet()); - generateCombinations(entries, 0, new LinkedMultiValueMap<>(), allMultiValueMaps); + public static List> generateAllMultiValueMaps( + Map> properties) { + List> allMultiValueMaps = new ArrayList<>(); - return allMultiValueMaps; + if (properties.isEmpty()) { + allMultiValueMaps.add( + new LinkedMultiValueMap<>()); // Add an empty map for the case where all are null + return allMultiValueMaps; } - private static void generateCombinations( - List>> entries, - int index, - MultiValueMap currentMap, - List> allMultiValueMaps) { + List>> entries = new ArrayList<>(properties.entrySet()); + generateCombinations(entries, 0, new LinkedMultiValueMap<>(), allMultiValueMaps); - if (index == entries.size()) { - allMultiValueMaps.add(new LinkedMultiValueMap<>(currentMap)); - return; - } + return allMultiValueMaps; + } - Entry> currentEntry = entries.get(index); - String key = currentEntry.getKey(); - List values = currentEntry.getValue(); - - // Add the other options - for (String value : values) { - LinkedMultiValueMap nextMapWithValue = new LinkedMultiValueMap<>(currentMap); - if (value.startsWith(NEGATE)) { - nextMapWithValue.add(key + NEGATE, value.substring(1)); - } else { - nextMapWithValue.add(key, value); - } - generateCombinations(entries, index + 1, nextMapWithValue, allMultiValueMaps); - } + private static void generateCombinations( + List>> entries, + int index, + MultiValueMap currentMap, + List> allMultiValueMaps) { + + if (index == entries.size()) { + allMultiValueMaps.add(new LinkedMultiValueMap<>(currentMap)); + return; } - private List metricTagsFromMultiValueMap(MultiValueMap multiValueMap) { - List metricTags = new ArrayList<>(); - for (Map.Entry entry : multiValueMap.toSingleValueMap().entrySet()) { - 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())); - } - } else { - metricTags.add(new ImmutableTag(entry.getKey(), entry.getValue())); - } + Entry> currentEntry = entries.get(index); + String key = currentEntry.getKey(); + List values = currentEntry.getValue(); + + // Add the other options + for (String value : values) { + LinkedMultiValueMap nextMapWithValue = new LinkedMultiValueMap<>(currentMap); + if (value.startsWith(NEGATE)) { + nextMapWithValue.add(key + NEGATE, value.substring(1)); + } else { + nextMapWithValue.add(key, value); + } + generateCombinations(entries, index + 1, nextMapWithValue, allMultiValueMaps); + } + } + + private List metricTagsFromMultiValueMap(MultiValueMap multiValueMap) { + List metricTags = new ArrayList<>(); + for (Map.Entry entry : multiValueMap.toSingleValueMap().entrySet()) { + 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())); } - return metricTags; + } else { + metricTags.add(new ImmutableTag(entry.getKey(), entry.getValue())); + } } + return metricTags; + } - private void registerPropertyMetrics() { - Map> properties = parseProperties(); + private void registerPropertyMetrics() { + Map> properties = parseProperties(); - List> combinations = generateAllMultiValueMaps(properties); + List> combinations = generateAllMultiValueMaps(properties); - propertyMetrics = combinations.stream() + propertyMetrics = + combinations.stream() .map(t -> Map.entry(t, new AtomicLong(0))) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - combinations.forEach(map -> Gauge.builder(CF_CHANNEL_COUNT, propertyMetrics, m -> m.get(map).doubleValue()) - .description(METRIC_DESCRIPTION_CHANNEL_COUNT) - .tags(metricTagsFromMultiValueMap(map)) - .register(meterRegistry) - ); + combinations.forEach( + map -> + Gauge.builder(CF_CHANNEL_COUNT, propertyMetrics, m -> m.get(map).doubleValue()) + .description(METRIC_DESCRIPTION_CHANNEL_COUNT) + .tags(metricTagsFromMultiValueMap(map)) + .register(meterRegistry)); + } + + private void updateTagMetrics() { + for (Map.Entry tagMetricEntry : tagMetrics.entrySet()) { + tagMetricEntry.getValue().set(channelRepository.countByTag(tagMetricEntry.getKey())); } + } - private void updateTagMetrics() { - for (Map.Entry tagMetricEntry : tagMetrics.entrySet()) { - tagMetricEntry.getValue() - .set(channelRepository.countByTag(tagMetricEntry.getKey())); - } + private void updatePropertyMetrics() { + for (Map.Entry, AtomicLong> propertyMetricEntry : + propertyMetrics.entrySet()) { + propertyMetricEntry.getValue().set(channelRepository.count(propertyMetricEntry.getKey())); } + } - private void updatePropertyMetrics() { - for (Map.Entry, AtomicLong> propertyMetricEntry : propertyMetrics.entrySet()) { - propertyMetricEntry.getValue() - .set(channelRepository.count(propertyMetricEntry.getKey())); - } - } - - @Scheduled(fixedRateString = "${metrics.updateInterval}", timeUnit = TimeUnit.SECONDS) - public void updateMetrics() { - updateTagMetrics(); - updatePropertyMetrics(); - } + @Scheduled(fixedRateString = "${metrics.updateInterval}", timeUnit = TimeUnit.SECONDS) + public void updateMetrics() { + updateTagMetrics(); + updatePropertyMetrics(); + } } diff --git a/src/main/java/org/phoebus/channelfinder/PropertyManager.java b/src/main/java/org/phoebus/channelfinder/PropertyManager.java index 6434b9d4..a446989c 100644 --- a/src/main/java/org/phoebus/channelfinder/PropertyManager.java +++ b/src/main/java/org/phoebus/channelfinder/PropertyManager.java @@ -2,12 +2,13 @@ import static org.phoebus.channelfinder.CFResourceDescriptors.PROPERTY_RESOURCE_URI; +import com.google.common.collect.Lists; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -18,8 +19,6 @@ import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; - -import com.google.common.collect.Lists; import org.phoebus.channelfinder.AuthorizationService.ROLES; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; @@ -45,694 +44,750 @@ @EnableAutoConfiguration public class PropertyManager { - private static final Logger propertyManagerAudit = Logger.getLogger(PropertyManager.class.getName() + ".audit"); - private static final Logger logger = Logger.getLogger(PropertyManager.class.getName()); - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - AuthorizationService authorizationService; - - @Operation( - summary = "List all properties", - description = "Retrieve the list of all properties in the database.", - operationId = "listProperties", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "List of properties", - content = @Content( - array = - @ArraySchema(schema = @Schema(implementation = Property.class)))), - @ApiResponse( - responseCode = "500", - description = "Error while listing properties", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping - public Iterable list() { - return propertyRepository.findAll(); + private static final Logger propertyManagerAudit = + Logger.getLogger(PropertyManager.class.getName() + ".audit"); + private static final Logger logger = Logger.getLogger(PropertyManager.class.getName()); + + @Autowired TagRepository tagRepository; + + @Autowired PropertyRepository propertyRepository; + + @Autowired ChannelRepository channelRepository; + + @Autowired AuthorizationService authorizationService; + + @Operation( + summary = "List all properties", + description = "Retrieve the list of all properties in the database.", + operationId = "listProperties", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "List of properties", + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = Property.class)))), + @ApiResponse( + responseCode = "500", + description = "Error while listing properties", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping + public Iterable list() { + return propertyRepository.findAll(); + } + + @Operation( + summary = "Get property by name", + description = "Retrieve a property by its name. Optionally include its channels.", + operationId = "getPropertyByName", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Fetch property by propertyName", + content = @Content(schema = @Schema(implementation = Property.class))), + @ApiResponse( + responseCode = "404", + description = "Property not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/{propertyName}") + public Property read( + @PathVariable("propertyName") String propertyName, + @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels) { + propertyManagerAudit.log( + Level.INFO, () -> MessageFormat.format(TextUtil.FIND_PROPERTY, propertyName)); + + Optional foundProperty; + if (withChannels) { + foundProperty = propertyRepository.findById(propertyName, true); + } else { + foundProperty = propertyRepository.findById(propertyName); } - - @Operation( - summary = "Get property by name", - description = "Retrieve a property by its name. Optionally include its channels.", - operationId = "getPropertyByName", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Fetch property by propertyName", - content = @Content(schema = @Schema(implementation = Property.class))), - @ApiResponse( - responseCode = "404", - description = "Property not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/{propertyName}") - public Property read(@PathVariable("propertyName") String propertyName, - @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels) { - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.FIND_PROPERTY, propertyName)); - - Optional foundProperty; - if(withChannels) { - foundProperty = propertyRepository.findById(propertyName, true); - } else { - foundProperty = propertyRepository.findById(propertyName); - } - if (foundProperty.isPresent()) { - return foundProperty.get(); - } else { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + if (foundProperty.isPresent()) { + return foundProperty.get(); + } else { + String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); } - - @Operation( - summary = "Create or update a property", - description = "Create and exclusively update the property identified by the path parameter.", - operationId = "createOrUpdateProperty", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Property created", - content = @Content(schema = @Schema(implementation = Property.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create property", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/{propertyName}") - public Property create(@PathVariable("propertyName") String propertyName, @RequestBody Property property) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - long start = System.currentTimeMillis(); - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validatePropertyRequest(property); - - // check if authorized owner - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), property)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - Optional existingProperty = propertyRepository.findById(propertyName); - boolean present = existingProperty.isPresent(); - if(present) { - checkPropertyAuthorization(existingProperty); - // delete existing property - propertyRepository.deleteById(propertyName); - } - - // create new property - Property createdProperty = propertyRepository.index(property); - - if(!property.getChannels().isEmpty()) { - // update the listed channels in the property's payload with the new property - Iterable chans = channelRepository.saveAll(property.getChannels()); - // TODO validate the above result - List chanList = new ArrayList<>(); - for(Channel chan: chans) { - chanList.add(chan); - } - createdProperty.setChannels(chanList); - } - return createdProperty; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + @Operation( + summary = "Create or update a property", + description = "Create and exclusively update the property identified by the path parameter.", + operationId = "createOrUpdateProperty", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Property created", + content = @Content(schema = @Schema(implementation = Property.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create property", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/{propertyName}") + public Property create( + @PathVariable("propertyName") String propertyName, @RequestBody Property property) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + long start = System.currentTimeMillis(); + propertyManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validatePropertyRequest(property); + + // check if authorized owner + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), property)) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + Optional existingProperty = propertyRepository.findById(propertyName); + boolean present = existingProperty.isPresent(); + if (present) { + checkPropertyAuthorization(existingProperty); + // delete existing property + propertyRepository.deleteById(propertyName); + } + + // create new property + Property createdProperty = propertyRepository.index(property); + + if (!property.getChannels().isEmpty()) { + // update the listed channels in the property's payload with the new property + Iterable chans = channelRepository.saveAll(property.getChannels()); + // TODO validate the above result + List chanList = new ArrayList<>(); + for (Channel chan : chans) { + chanList.add(chan); } + createdProperty.setChannels(chanList); + } + return createdProperty; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Create multiple properties", - description = "Create multiple properties in a single request.", - operationId = "createMultipleProperties", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Properties created", - content = @Content(schema = @Schema(implementation = Property.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create properties", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping() - public Iterable create(@RequestBody Iterable properties) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - long start = System.currentTimeMillis(); - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - - // check if authorized owner - checkPropertiesAuthorization(properties); - - // Validate request parameters - validatePropertyRequest(properties); - - // delete existing property - for(Property property: properties) { - if(propertyRepository.existsById(property.getName())) { - // delete existing property - propertyRepository.deleteById(property.getName()); - } - } - - // create new properties - propertyRepository.indexAll(Lists.newArrayList(properties)); - - // update the listed channels in the properties' payloads with the new - // properties - Map channels = new HashMap<>(); - for(Property property: properties) { - for(Channel ch: property.getChannels()) { - if(channels.containsKey(ch.getName())) { - channels.get(ch.getName()).addProperties(ch.getProperties()); - } else { - channels.put(ch.getName(), ch); - } - } - } - - if(!channels.isEmpty()) { - Iterable chans = channelRepository.saveAll(channels.values()); - } - // TODO should return created props with properly organized saved channels, but it would be very complicated... - return properties; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTIES, properties); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + @Operation( + summary = "Create multiple properties", + description = "Create multiple properties in a single request.", + operationId = "createMultipleProperties", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Properties created", + content = @Content(schema = @Schema(implementation = Property.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create properties", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping() + public Iterable create(@RequestBody Iterable properties) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + long start = System.currentTimeMillis(); + propertyManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + + // check if authorized owner + checkPropertiesAuthorization(properties); + + // Validate request parameters + validatePropertyRequest(properties); + + // delete existing property + for (Property property : properties) { + if (propertyRepository.existsById(property.getName())) { + // delete existing property + propertyRepository.deleteById(property.getName()); } - } - - @Operation( - summary = "Add property to a single channel", - description = "Add the property identified by propertyName to the channel identified by channelName.", - operationId = "addPropertyToChannel", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Property added to the channel", - content = @Content(schema = @Schema(implementation = Property.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property-, or Channel-name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to add property", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/{propertyName}/{channelName}") - public Property addSingle(@PathVariable("propertyName") String propertyName, @PathVariable("channelName") String channelName, @RequestBody Property property) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - long start = System.currentTimeMillis(); - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validatePropertyRequest(channelName); - if(!propertyName.equals(property.getName()) || property.getValue().isEmpty() || property.getValue() == null) { - String message = MessageFormat.format(TextUtil.PAYLOAD_PROPERTY_DOES_NOT_MATCH_URI_OR_HAS_BAD_VALUE, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); - } - - // check if authorized owner - Optional existingProperty = propertyRepository.findById(propertyName); - boolean present = existingProperty.isPresent(); - if(present) { - checkPropertyAuthorization(existingProperty); - // add property to channel - Channel channel = channelRepository.findById(channelName).get(); - Property prop = existingProperty.get(); - channel.addProperty(new Property(prop.getName(),prop.getOwner(),property.getValue())); - Channel taggedChannel = channelRepository.save(channel); - Property addedProperty = new Property(prop.getName(),prop.getOwner(),property.getValue()); - taggedChannel.setTags(new ArrayList<>()); - taggedChannel.setProperties(new ArrayList<>()); - addedProperty.setChannels(Arrays.asList(taggedChannel)); - return addedProperty; - } else { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + // create new properties + propertyRepository.indexAll(Lists.newArrayList(properties)); + + // update the listed channels in the properties' payloads with the new + // properties + Map channels = new HashMap<>(); + for (Property property : properties) { + for (Channel ch : property.getChannels()) { + if (channels.containsKey(ch.getName())) { + channels.get(ch.getName()).addProperties(ch.getProperties()); + } else { + channels.put(ch.getName(), ch); + } } + } + + if (!channels.isEmpty()) { + Iterable chans = channelRepository.saveAll(channels.values()); + } + // TODO should return created props with properly organized saved channels, but it would be + // very complicated... + return properties; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTIES, properties); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + } + + @Operation( + summary = "Add property to a single channel", + description = + "Add the property identified by propertyName to the channel identified by channelName.", + operationId = "addPropertyToChannel", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Property added to the channel", + content = @Content(schema = @Schema(implementation = Property.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property-, or Channel-name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to add property", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/{propertyName}/{channelName}") + public Property addSingle( + @PathVariable("propertyName") String propertyName, + @PathVariable("channelName") String channelName, + @RequestBody Property property) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + long start = System.currentTimeMillis(); + propertyManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validatePropertyRequest(channelName); + if (!propertyName.equals(property.getName()) + || property.getValue().isEmpty() + || property.getValue() == null) { + String message = + MessageFormat.format( + TextUtil.PAYLOAD_PROPERTY_DOES_NOT_MATCH_URI_OR_HAS_BAD_VALUE, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); + } + + // check if authorized owner + Optional existingProperty = propertyRepository.findById(propertyName); + boolean present = existingProperty.isPresent(); + if (present) { + checkPropertyAuthorization(existingProperty); + // add property to channel + Channel channel = channelRepository.findById(channelName).get(); + Property prop = existingProperty.get(); + channel.addProperty(new Property(prop.getName(), prop.getOwner(), property.getValue())); + Channel taggedChannel = channelRepository.save(channel); + Property addedProperty = new Property(prop.getName(), prop.getOwner(), property.getValue()); + taggedChannel.setTags(new ArrayList<>()); + taggedChannel.setProperties(new ArrayList<>()); + addedProperty.setChannels(Arrays.asList(taggedChannel)); + return addedProperty; + } else { + String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + } + + @Operation( + summary = "Update a property", + description = + "Update the property identified by the path parameter, adding it to all channels in the payload.", + operationId = "updateProperty", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Property updated", + content = @Content(schema = @Schema(implementation = Property.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to update property", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping("/{propertyName}") + public Property update( + @PathVariable("propertyName") String propertyName, @RequestBody Property property) { + // check if authorized role + if (!authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - @Operation( - summary = "Update a property", - description = "Update the property identified by the path parameter, adding it to all channels in the payload.", - operationId = "updateProperty", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Property updated", - content = @Content(schema = @Schema(implementation = Property.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to update property", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping("/{propertyName}") - public Property update(@PathVariable("propertyName") String propertyName, @RequestBody Property property) { - // check if authorized role - if(!authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - - long start = System.currentTimeMillis(); - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validatePropertyRequest(property); - - // check if authorized owner - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), property)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - - List chans = new ArrayList<>(); - Optional existingProperty = propertyRepository.findById(propertyName,true); - Property newProperty; - if(existingProperty.isPresent()) { - checkPropertyAuthorization(existingProperty); - chans = existingProperty.get().getChannels(); - newProperty = existingProperty.get(); - newProperty.setOwner(property.getOwner()); - // Is an existing channel being renamed - if (!property.getName().equalsIgnoreCase(existingProperty.get().getName())) { - // Since this is a rename operation we will need to remove the old channel. - propertyRepository.deleteById(existingProperty.get().getName()); - newProperty.setName(property.getName()); - } - } else { - newProperty = property; - } + long start = System.currentTimeMillis(); + propertyManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validatePropertyRequest(property); + + // check if authorized owner + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), property)) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } - // update property - Property updatedProperty = propertyRepository.save(newProperty); - - // update channels of existing property - if(!chans.isEmpty()) { - List chanList = new ArrayList<>(); - for(Channel chan: chans) { - boolean alreadyUpdated = updatedProperty.getChannels().stream() - .anyMatch(c -> c.getName().equals(chan.getName())); - - if(!alreadyUpdated) { - Optional value = chan.getProperties().stream() - .filter(p -> p.getName().equals(propertyName)) - .findFirst() - .map(Property::getValue); - if (value.isPresent()) { - Property prop = new Property(property.getName(),property.getOwner(),value.get()); - chan.setProperties(List.of(prop)); - chanList.add(chan); - } - } - } - if(!chanList.isEmpty()) - channelRepository.saveAll(chanList); - } + List chans = new ArrayList<>(); + Optional existingProperty = propertyRepository.findById(propertyName, true); + Property newProperty; + if (existingProperty.isPresent()) { + checkPropertyAuthorization(existingProperty); + chans = existingProperty.get().getChannels(); + newProperty = existingProperty.get(); + newProperty.setOwner(property.getOwner()); + // Is an existing channel being renamed + if (!property.getName().equalsIgnoreCase(existingProperty.get().getName())) { + // Since this is a rename operation we will need to remove the old channel. + propertyRepository.deleteById(existingProperty.get().getName()); + newProperty.setName(property.getName()); + } + } else { + newProperty = property; + } - if(!property.getChannels().isEmpty()) { - // update the listed channels in the property's payloads with the new property - Iterable channels = channelRepository.saveAll(property.getChannels()); - List chanList = new ArrayList<>(); - Property p = null; - for(Channel chan: channels) { - chan.setTags(new ArrayList<>()); - for(Property prop: chan.getProperties()) - { - if(prop.getName().equals(propertyName)) - p = prop; - } - chan.setProperties(Collections.singletonList(p)); - chanList.add(chan); - } - if(!chanList.isEmpty()) - updatedProperty.setChannels(chanList); + // update property + Property updatedProperty = propertyRepository.save(newProperty); + + // update channels of existing property + if (!chans.isEmpty()) { + List chanList = new ArrayList<>(); + for (Channel chan : chans) { + boolean alreadyUpdated = + updatedProperty.getChannels().stream() + .anyMatch(c -> c.getName().equals(chan.getName())); + + if (!alreadyUpdated) { + Optional value = + chan.getProperties().stream() + .filter(p -> p.getName().equals(propertyName)) + .findFirst() + .map(Property::getValue); + if (value.isPresent()) { + Property prop = new Property(property.getName(), property.getOwner(), value.get()); + chan.setProperties(List.of(prop)); + chanList.add(chan); + } } - - return updatedProperty; + } + if (!chanList.isEmpty()) channelRepository.saveAll(chanList); } - @Operation( - summary = "Update multiple properties", - description = "Update multiple properties and all appropriate channels.", - operationId = "updateMultipleProperties", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Properties updated", - content = @Content( - array = @ArraySchema(schema = @Schema(implementation = Property.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to update properties", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping() - public Iterable update(@RequestBody Iterable properties) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - long start = System.currentTimeMillis(); - propertyManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - - // check if authorized owner - checkPropertiesAuthorization(properties); - - // Validate request parameters - validatePropertyRequest(properties); - - // prepare the list of channels which need to be updated with the new properties - Map channels = new HashMap<>(); - - // import the old properties - for(Property property: properties) { - if(propertyRepository.existsById(property.getName())) { - for(Channel ch: propertyRepository.findById(property.getName(),true).get().getChannels()) { - if(channels.containsKey(ch.getName())) { - channels.get(ch.getName()).addProperties(ch.getProperties()); - } else { - channels.put(ch.getName(), ch); - } - } - } - } - // set the new properties - for(Property property: properties) { - for(Channel ch: property.getChannels()) { - if(channels.containsKey(ch.getName())) { - channels.get(ch.getName()).addProperties(ch.getProperties()); - } else { - channels.put(ch.getName(), ch); - } - } - } - - // update properties - Iterable updatedProperties = propertyRepository.saveAll(properties); - - // update channels - if(!channels.isEmpty()) { - channelRepository.saveAll(channels.values()); - } - // TODO should return updated props with properly organized saved channels, but it would be very complicated... - return properties; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTIES, properties); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + if (!property.getChannels().isEmpty()) { + // update the listed channels in the property's payloads with the new property + Iterable channels = channelRepository.saveAll(property.getChannels()); + List chanList = new ArrayList<>(); + Property p = null; + for (Channel chan : channels) { + chan.setTags(new ArrayList<>()); + for (Property prop : chan.getProperties()) { + if (prop.getName().equals(propertyName)) p = prop; } + chan.setProperties(Collections.singletonList(p)); + chanList.add(chan); + } + if (!chanList.isEmpty()) updatedProperty.setChannels(chanList); } - private void checkPropertiesAuthorization(Iterable properties) { - for(Property property: properties) { - Optional existingProperty = propertyRepository.findById(property.getName()); - boolean present = existingProperty.isPresent(); - if(present) { - checkPropertyAuthorization(existingProperty); - property.setOwner(existingProperty.get().getOwner()); - property.getChannels().forEach(chan -> chan.getProperties().get(0).setOwner(existingProperty.get().getOwner())); + return updatedProperty; + } + + @Operation( + summary = "Update multiple properties", + description = "Update multiple properties and all appropriate channels.", + operationId = "updateMultipleProperties", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Properties updated", + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = Property.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to update properties", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping() + public Iterable update(@RequestBody Iterable properties) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + long start = System.currentTimeMillis(); + propertyManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + + // check if authorized owner + checkPropertiesAuthorization(properties); + + // Validate request parameters + validatePropertyRequest(properties); + + // prepare the list of channels which need to be updated with the new properties + Map channels = new HashMap<>(); + + // import the old properties + for (Property property : properties) { + if (propertyRepository.existsById(property.getName())) { + for (Channel ch : + propertyRepository.findById(property.getName(), true).get().getChannels()) { + if (channels.containsKey(ch.getName())) { + channels.get(ch.getName()).addProperties(ch.getProperties()); } else { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), property)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } + channels.put(ch.getName(), ch); } + } + } + } + // set the new properties + for (Property property : properties) { + for (Channel ch : property.getChannels()) { + if (channels.containsKey(ch.getName())) { + channels.get(ch.getName()).addProperties(ch.getProperties()); + } else { + channels.put(ch.getName(), ch); + } } + } + + // update properties + Iterable updatedProperties = propertyRepository.saveAll(properties); + + // update channels + if (!channels.isEmpty()) { + channelRepository.saveAll(channels.values()); + } + // TODO should return updated props with properly organized saved channels, but it would be + // very complicated... + return properties; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTIES, properties); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - private void checkPropertyAuthorization(Optional existingProperty) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, existingProperty.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + private void checkPropertiesAuthorization(Iterable properties) { + for (Property property : properties) { + Optional existingProperty = propertyRepository.findById(property.getName()); + boolean present = existingProperty.isPresent(); + if (present) { + checkPropertyAuthorization(existingProperty); + property.setOwner(existingProperty.get().getOwner()); + property + .getChannels() + .forEach( + chan -> chan.getProperties().get(0).setOwner(existingProperty.get().getOwner())); + } else { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), property)) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } } - - @Operation( - summary = "Delete a property", - description = "Delete the property identified by the path parameter from all channels.", - operationId = "deleteProperty", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Property deleted"), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to delete property", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @DeleteMapping("/{propertyName}") - public void remove(@PathVariable("propertyName") String propertyName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - Optional existingProperty = propertyRepository.findById(propertyName); - if(existingProperty.isPresent()) { - // check if authorized owner - if(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { - // delete property - propertyRepository.deleteById(propertyName); - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } else { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + private void checkPropertyAuthorization(Optional existingProperty) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { + String message = + MessageFormat.format( + TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, existingProperty.get().toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + } + + @Operation( + summary = "Delete a property", + description = "Delete the property identified by the path parameter from all channels.", + operationId = "deleteProperty", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Property deleted"), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to delete property", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @DeleteMapping("/{propertyName}") + public void remove(@PathVariable("propertyName") String propertyName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + Optional existingProperty = propertyRepository.findById(propertyName); + if (existingProperty.isPresent()) { + // check if authorized owner + if (authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { + // delete property + propertyRepository.deleteById(propertyName); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } else { + String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Delete property from a channel", - description = "Delete the property identified by propertyName from the channel identified by channelName.", - operationId = "deletePropertyFromChannel", - tags = {"Property"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Property deleted from the channel"), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Property does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to delete property from a channel", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @DeleteMapping("/{propertyName}/{channelName}") - public void removeSingle(@PathVariable("propertyName") final String propertyName, @PathVariable("channelName") String channelName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { - Optional existingProperty = propertyRepository.findById(propertyName); - if(existingProperty.isPresent()) { - // check if authorized owner - if(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { - Optional ch = channelRepository.findById(channelName); - if(ch.isPresent()) { - // remove property from channel - Channel channel = ch.get(); - channel.removeProperty(new Property(propertyName, "")); - channelRepository.index(channel); - } else { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } else { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + @Operation( + summary = "Delete property from a channel", + description = + "Delete the property identified by propertyName from the channel identified by channelName.", + operationId = "deletePropertyFromChannel", + tags = {"Property"}) + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Property deleted from the channel"), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Property does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to delete property from a channel", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @DeleteMapping("/{propertyName}/{channelName}") + public void removeSingle( + @PathVariable("propertyName") final String propertyName, + @PathVariable("channelName") String channelName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY)) { + Optional existingProperty = propertyRepository.findById(propertyName); + if (existingProperty.isPresent()) { + // check if authorized owner + if (authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingProperty.get())) { + Optional ch = channelRepository.findById(channelName); + if (ch.isPresent()) { + // remove property from channel + Channel channel = ch.get(); + channel.removeProperty(new Property(propertyName, "")); + channelRepository.index(channel); + } else { + String message = + MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } else { + String message = MessageFormat.format(TextUtil.PROPERTY_NAME_DOES_NOT_EXIST, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_PROPERTY, propertyName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - /** - * Checks if - * 1. the property name is not null and matches the name in the body - * 2. the property owner is not null or empty - * 3. all the listed channels exist and have the property with a non null and non empty value - * - * @param property validate property - */ - public void validatePropertyRequest(Property property) { - // 1 - if (property.getName() == null || property.getName().isEmpty()) { - String message = MessageFormat.format(TextUtil.PROPERTY_NAME_CANNOT_BE_NULL_OR_EMPTY, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); - } - // 2 - if (property.getOwner() == null || property.getOwner().isEmpty()) { - String message = MessageFormat.format(TextUtil.PROPERTY_OWNER_CANNOT_BE_NULL_OR_EMPTY, property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); - } - // 3 - property.getChannels().stream().forEach((channel) -> { - // Check if all the channels exists - if(!channelRepository.existsById(channel.getName())) { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channel.getName()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + } + + /** + * Checks if 1. the property name is not null and matches the name in the body 2. the property + * owner is not null or empty 3. all the listed channels exist and have the property with a non + * null and non empty value + * + * @param property validate property + */ + public void validatePropertyRequest(Property property) { + // 1 + if (property.getName() == null || property.getName().isEmpty()) { + String message = + MessageFormat.format(TextUtil.PROPERTY_NAME_CANNOT_BE_NULL_OR_EMPTY, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); + } + // 2 + if (property.getOwner() == null || property.getOwner().isEmpty()) { + String message = + MessageFormat.format(TextUtil.PROPERTY_OWNER_CANNOT_BE_NULL_OR_EMPTY, property.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); + } + // 3 + property.getChannels().stream() + .forEach( + (channel) -> { + // Check if all the channels exists + if (!channelRepository.existsById(channel.getName())) { + String message = + MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channel.getName()); + logger.log( + Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); - } - // Check if the channel data has the requested property attached with a non null - non empty value - if(!channel.getProperties().stream().anyMatch(p -> - p.getName().equals(property.getName()) && p.getValue() != null && !p.getValue().isEmpty() - )) { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_NO_VALID_INSTANCE_PROPERTY, channel.getName(), property.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + } + // Check if the channel data has the requested property attached with a non null - non + // empty value + if (!channel.getProperties().stream() + .anyMatch( + p -> + p.getName().equals(property.getName()) + && p.getValue() != null + && !p.getValue().isEmpty())) { + String message = + MessageFormat.format( + TextUtil.CHANNEL_NAME_NO_VALID_INSTANCE_PROPERTY, + channel.getName(), + property.toLog()); + logger.log( + Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message); - } - }); - } - - /** - * Checks if - * 1. the property name is not null and matches the name in the body - * 2. the property owner is not null or empty - * 3. the property value is not null or empty - * 4. all the listed channels exist - * - * @param properties properties to be validated - */ - public void validatePropertyRequest(Iterable properties) { - for(Property property: properties) { - validatePropertyRequest(property); - } + } + }); + } + + /** + * Checks if 1. the property name is not null and matches the name in the body 2. the property + * owner is not null or empty 3. the property value is not null or empty 4. all the listed + * channels exist + * + * @param properties properties to be validated + */ + public void validatePropertyRequest(Iterable properties) { + for (Property property : properties) { + validatePropertyRequest(property); } - - /** - * Checks if the channel exists - * @param channelName check channel exists - */ - public void validatePropertyRequest(String channelName) { - if(!channelRepository.existsById(channelName)) { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + /** + * Checks if the channel exists + * + * @param channelName check channel exists + */ + public void validatePropertyRequest(String channelName) { + if (!channelRepository.existsById(channelName)) { + String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); } - + } } diff --git a/src/main/java/org/phoebus/channelfinder/PropertyRepository.java b/src/main/java/org/phoebus/channelfinder/PropertyRepository.java index 3cd864a9..7b2a0114 100644 --- a/src/main/java/org/phoebus/channelfinder/PropertyRepository.java +++ b/src/main/java/org/phoebus/channelfinder/PropertyRepository.java @@ -1,13 +1,6 @@ package org.phoebus.channelfinder; -import java.io.IOException; -import java.text.MessageFormat; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.StreamSupport; - +import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.ElasticsearchException; import co.elastic.clients.elasticsearch._types.FieldSort; import co.elastic.clients.elasticsearch._types.Refresh; @@ -30,19 +23,23 @@ import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.JsonData; import co.elastic.clients.json.jackson.JacksonJsonpMapper; -import org.phoebus.channelfinder.entity.Property.OnlyNameOwnerProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.StreamSupport; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; +import org.phoebus.channelfinder.entity.Property.OnlyNameOwnerProperty; 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 com.fasterxml.jackson.databind.ObjectMapper; - -import co.elastic.clients.elasticsearch.ElasticsearchClient; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; @@ -51,346 +48,368 @@ @Configuration public class PropertyRepository implements CrudRepository { - private static final Logger logger = Logger.getLogger(PropertyRepository.class.getName()); - - @Autowired - @Qualifier("indexClient") - ElasticsearchClient client; - - @Autowired - ElasticConfig esService; - - @Autowired - ChannelRepository channelRepository; - - ObjectMapper objectMapper = new ObjectMapper().addMixIn(Property.class, OnlyNameOwnerProperty.class); - - /** - * create a new property using the given Property - * - * @param property - property to be created - * @return the created property - */ - public Property index(Property property) { - return save(property.getName(), property); + private static final Logger logger = Logger.getLogger(PropertyRepository.class.getName()); + + @Autowired + @Qualifier("indexClient") + ElasticsearchClient client; + + @Autowired ElasticConfig esService; + + @Autowired ChannelRepository channelRepository; + + ObjectMapper objectMapper = + new ObjectMapper().addMixIn(Property.class, OnlyNameOwnerProperty.class); + + /** + * create a new property using the given Property + * + * @param property - property to be created + * @return the created property + */ + public Property index(Property property) { + return save(property.getName(), property); + } + + /** + * create new properties using the given XmlProperties + * + * @param properties - properties to be created + * @return the created properties + */ + public List indexAll(List properties) { + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Property property : properties) { + br.operations( + op -> + op.index( + idx -> + idx.index(esService.getES_PROPERTY_INDEX()) + .id(property.getName()) + .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))))); } - - /** - * create new properties using the given XmlProperties - * - * @param properties - properties to be created - * @return the created properties - */ - public List indexAll(List properties) { - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Property property : properties) { - br.operations(op -> op - .index(idx -> idx - .index(esService.getES_PROPERTY_INDEX()) - .id(property.getName()) - .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))) - ) - ); - } - try { - BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } else { - return findAllById(properties.stream().map(Property::getName).toList()); - } - } 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); - + try { + BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - return null; + } else { + return findAllById(properties.stream().map(Property::getName).toList()); + } + } 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); } - - /** - * update/save property using the given Property - * - * @param extends Property - * @param propertyName - name of property to be created - * @param property - property to be created - * @return the updated/saved property - */ - @SuppressWarnings("unchecked") - public S save(String propertyName, S property) { - try { - IndexRequest request = IndexRequest.of(i -> i.index(esService.getES_PROPERTY_INDEX()) - .id(propertyName) - .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))) - .refresh(Refresh.True)); - - IndexResponse response = client.index(request); - // verify the creation of the tag - if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_PROPERTY, property.toLog())); - return (S) findById(propertyName).get(); - } - } 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); - } - return null; + return null; + } + + /** + * update/save property using the given Property + * + * @param extends Property + * @param propertyName - name of property to be created + * @param property - property to be created + * @return the updated/saved property + */ + @SuppressWarnings("unchecked") + public S save(String propertyName, S property) { + try { + IndexRequest request = + IndexRequest.of( + i -> + i.index(esService.getES_PROPERTY_INDEX()) + .id(propertyName) + .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))) + .refresh(Refresh.True)); + + IndexResponse response = client.index(request); + // verify the creation of the tag + if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_PROPERTY, property.toLog())); + return (S) findById(propertyName).get(); + } + } 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); } - - /** - * @param extends Property - */ - @Override - public S save(S property) { - return save(property.getName(), property); + return null; + } + + /** + * @param extends Property + */ + @Override + public S save(S property) { + return save(property.getName(), property); + } + + /** + * update/save properties using the given XmlProperties + * + * @param extends Property + * @param properties - properties to be created + * @return the updated/saved properties + */ + @SuppressWarnings("unchecked") + @Override + public Iterable saveAll(Iterable properties) { + List ids = + StreamSupport.stream(properties.spliterator(), false).map(Property::getName).toList(); + + BulkRequest.Builder br = new BulkRequest.Builder(); + + for (Property property : properties) { + br.operations( + op -> + op.index( + i -> + i.index(esService.getES_PROPERTY_INDEX()) + .id(property.getName()) + .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))))); } - /** - * update/save properties using the given XmlProperties - * - * @param extends Property - * @param properties - properties to be created - * @return the updated/saved properties - */ - @SuppressWarnings("unchecked") - @Override - public Iterable saveAll(Iterable properties) { - List ids = StreamSupport.stream(properties.spliterator(), false) - .map(Property::getName).toList(); - - BulkRequest.Builder br = new BulkRequest.Builder(); - - for (Property property : properties) { - br.operations(op -> op.index(i -> i.index(esService.getES_PROPERTY_INDEX()) - .id(property.getName()) - .document(JsonData.of(property, new JacksonJsonpMapper(objectMapper))))); - } - - try { - BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - // TODO cleanup? or throw exception? - } else { - return (Iterable) findAllById(ids); - } - } 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); + try { + BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - return null; + // TODO cleanup? or throw exception? + } else { + return (Iterable) findAllById(ids); + } + } 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); } - - /** - * find property using the given property id - * - * @param propertyId - id of property to be found - * @return the found property - */ - @Override - public Optional findById(String propertyId) { - return findById(propertyId, false); - } - - /** - * find property using the given property id - * - * @param propertyName - id of property to be found - * @param withChannels - whether channels should be included - * @return the found property - */ - public Optional findById(String propertyName, boolean withChannels) { - GetResponse response; - try { - response = client.get(g -> g.index(esService.getES_PROPERTY_INDEX()).id(propertyName), Property.class); - - if (response.found()) { - Property property = response.source(); - 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()); - } - return Optional.of(property); - } else { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.PROPERTY_NOT_FOUND, propertyName)); - return Optional.empty(); - } - } 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); + return null; + } + + /** + * find property using the given property id + * + * @param propertyId - id of property to be found + * @return the found property + */ + @Override + public Optional findById(String propertyId) { + return findById(propertyId, false); + } + + /** + * find property using the given property id + * + * @param propertyName - id of property to be found + * @param withChannels - whether channels should be included + * @return the found property + */ + public Optional findById(String propertyName, boolean withChannels) { + GetResponse response; + try { + response = + client.get( + g -> g.index(esService.getES_PROPERTY_INDEX()).id(propertyName), Property.class); + + if (response.found()) { + Property property = response.source(); + 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()); } + return Optional.of(property); + } else { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.PROPERTY_NOT_FOUND, propertyName)); + return Optional.empty(); + } + } 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); } - - @Override - public boolean existsById(String id) { - try { - ExistsRequest.Builder builder = new ExistsRequest.Builder(); - builder.index(esService.getES_PROPERTY_INDEX()).id(id); - return client.exists(builder.build()).value(); - } 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); - } + } + + @Override + public boolean existsById(String id) { + try { + ExistsRequest.Builder builder = new ExistsRequest.Builder(); + builder.index(esService.getES_PROPERTY_INDEX()).id(id); + return client.exists(builder.build()).value(); + } 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); } - - /** - * find all properties - * - * @return the found properties - */ - @Override - public Iterable findAll() { - try { - SearchRequest.Builder searchBuilder = new SearchRequest.Builder() - .index(esService.getES_PROPERTY_INDEX()) - .query(new MatchAllQuery.Builder().build()._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Property.class); - 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); - } + } + + /** + * find all properties + * + * @return the found properties + */ + @Override + public Iterable findAll() { + try { + SearchRequest.Builder searchBuilder = + new SearchRequest.Builder() + .index(esService.getES_PROPERTY_INDEX()) + .query(new MatchAllQuery.Builder().build()._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Property.class); + 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); } - - /** - * find properties using the given property ids - * - * @param propertyIds - ids of properties to be found - * @return the found properties - */ - @Override - public List findAllById(Iterable propertyIds) { - try { - List ids = StreamSupport.stream(propertyIds.spliterator(), false).toList(); - - SearchRequest.Builder searchBuilder = new SearchRequest.Builder() - .index(esService.getES_PROPERTY_INDEX()) - .query(IdsQuery.of(q -> q.values(ids))._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Property.class); - 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); - } + } + + /** + * find properties using the given property ids + * + * @param propertyIds - ids of properties to be found + * @return the found properties + */ + @Override + public List findAllById(Iterable propertyIds) { + try { + List ids = StreamSupport.stream(propertyIds.spliterator(), false).toList(); + + SearchRequest.Builder searchBuilder = + new SearchRequest.Builder() + .index(esService.getES_PROPERTY_INDEX()) + .query(IdsQuery.of(q -> q.values(ids))._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Property.class); + 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); } - - @Override - public long count() { - try { - CountRequest countRequest = new CountRequest.Builder().index(esService.getES_PROPERTY_INDEX()).build(); - CountResponse countResponse = client.count(countRequest); - return countResponse.count(); - } catch (ElasticsearchException | IOException e) { - - 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); - } + } + + @Override + public long count() { + try { + CountRequest countRequest = + new CountRequest.Builder().index(esService.getES_PROPERTY_INDEX()).build(); + CountResponse countResponse = client.count(countRequest); + return countResponse.count(); + } catch (ElasticsearchException | IOException e) { + + 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); } - - /** - * delete the given property by property name - * - * @param propertyName - name of property to be deleted - */ - @Override - public void deleteById(String propertyName) { + } + + /** + * delete the given property by property name + * + * @param propertyName - name of property to be deleted + */ + @Override + public void deleteById(String propertyName) { + try { + DeleteResponse response = + client.delete( + i -> + i.index(esService.getES_PROPERTY_INDEX()).id(propertyName).refresh(Refresh.True)); + // verify the deletion of the property + if (response.result().equals(Result.Deleted)) { + logger.log( + Level.CONFIG, () -> MessageFormat.format(TextUtil.DELETE_PROPERTY, propertyName)); + } + + // Remove the Property from Channels + BulkRequest.Builder br = new BulkRequest.Builder().refresh(Refresh.True); + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add(propertyName, "*"); + List channels = channelRepository.search(params).channels(); + while (channels.size() > 0) { + for (Channel channel : channels) { + channel.removeProperty( + channel.getProperties().stream() + .filter(prop -> propertyName.equalsIgnoreCase(prop.getName())) + .findAny() + .get()); + br.operations( + op -> + op.update( + u -> + u.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .action(a -> a.doc(channel)))); + } try { - DeleteResponse response = client - .delete(i -> i.index(esService.getES_PROPERTY_INDEX()).id(propertyName).refresh(Refresh.True)); - // verify the deletion of the property - if (response.result().equals(Result.Deleted)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.DELETE_PROPERTY, propertyName)); - } - - // Remove the Property from Channels - BulkRequest.Builder br = new BulkRequest.Builder().refresh(Refresh.True); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(propertyName, "*"); - List channels = channelRepository.search(params).channels(); - while (channels.size() > 0) { - for (Channel channel : channels) { - channel.removeProperty( - channel.getProperties().stream().filter(prop -> propertyName.equalsIgnoreCase(prop.getName())).findAny().get()); - br.operations(op -> op.update( - u -> u.index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .action(a -> a.doc(channel)))); - } - try { - br.refresh(Refresh.True); - BulkResponse result = client.bulk(br.build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } else { - } - } 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); - - } - params.set("~search_after", channels.get(channels.size() - 1).getName()); - channels = channelRepository.search(params).channels(); + br.refresh(Refresh.True); + BulkResponse result = client.bulk(br.build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - } 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); + } else { + } + } 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); } + params.set("~search_after", channels.get(channels.size() - 1).getName()); + channels = channelRepository.search(params).channels(); + } + } 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); } - - /** - * delete the given property - * - * @param property - property to be deleted - */ - @Override - public void delete(Property property) { - deleteById(property.getName()); - } - - @Override - public void deleteAll(Iterable entities) { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - - @Override - public void deleteAll() { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - - @Override - public void deleteAllById(Iterable ids) { - // TODO Auto-generated method stub - } - + } + + /** + * delete the given property + * + * @param property - property to be deleted + */ + @Override + public void delete(Property property) { + deleteById(property.getName()); + } + + @Override + public void deleteAll(Iterable entities) { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } + + @Override + public void deleteAll() { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } + + @Override + public void deleteAllById(Iterable ids) { + // TODO Auto-generated method stub + } } diff --git a/src/main/java/org/phoebus/channelfinder/RequestLoggingFilterConfig.java b/src/main/java/org/phoebus/channelfinder/RequestLoggingFilterConfig.java index 6f01411a..a83bb57f 100644 --- a/src/main/java/org/phoebus/channelfinder/RequestLoggingFilterConfig.java +++ b/src/main/java/org/phoebus/channelfinder/RequestLoggingFilterConfig.java @@ -7,15 +7,14 @@ @Configuration public class RequestLoggingFilterConfig { - @Bean - public CommonsRequestLoggingFilter logFilter() { - CommonsRequestLoggingFilter filter - = new CommonsRequestLoggingFilter(); - filter.setIncludeQueryString(true); - filter.setIncludePayload(true); - filter.setMaxPayloadLength(10000); - filter.setIncludeHeaders(false); - filter.setAfterMessagePrefix("REQUEST DATA : "); - return filter; - } -} \ No newline at end of file + @Bean + public CommonsRequestLoggingFilter logFilter() { + CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); + filter.setIncludeQueryString(true); + filter.setIncludePayload(true); + filter.setMaxPayloadLength(10000); + filter.setIncludeHeaders(false); + filter.setAfterMessagePrefix("REQUEST DATA : "); + return filter; + } +} diff --git a/src/main/java/org/phoebus/channelfinder/TagManager.java b/src/main/java/org/phoebus/channelfinder/TagManager.java index ffec21a3..f831ec12 100644 --- a/src/main/java/org/phoebus/channelfinder/TagManager.java +++ b/src/main/java/org/phoebus/channelfinder/TagManager.java @@ -2,12 +2,13 @@ import static org.phoebus.channelfinder.CFResourceDescriptors.TAG_RESOURCE_URI; +import com.google.common.collect.Lists; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -19,8 +20,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.StreamSupport; - -import com.google.common.collect.Lists; import org.phoebus.channelfinder.AuthorizationService.ROLES; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Tag; @@ -46,690 +45,729 @@ @EnableAutoConfiguration public class TagManager { - private static final Logger tagManagerAudit = Logger.getLogger(TagManager.class.getName() + ".audit"); - private static final Logger logger = Logger.getLogger(TagManager.class.getName()); - - @Autowired - TagRepository tagRepository; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - AuthorizationService authorizationService; - - @Operation( - summary = "List all tags", - description = "Retrieve the list of all tags in the database.", - operationId = "listTags", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "List all Tags", - content = @Content( - array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to list all Tags", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping - public Iterable list() { - return tagRepository.findAll(); + private static final Logger tagManagerAudit = + Logger.getLogger(TagManager.class.getName() + ".audit"); + private static final Logger logger = Logger.getLogger(TagManager.class.getName()); + + @Autowired TagRepository tagRepository; + + @Autowired ChannelRepository channelRepository; + + @Autowired AuthorizationService authorizationService; + + @Operation( + summary = "List all tags", + description = "Retrieve the list of all tags in the database.", + operationId = "listTags", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "List all Tags", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to list all Tags", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping + public Iterable list() { + return tagRepository.findAll(); + } + + @Operation( + summary = "Get tag by name", + description = "Retrieve a tag by its name. Optionally include its channels.", + operationId = "getTagByName", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Finding Tag by tagName", + content = @Content(schema = @Schema(implementation = Tag.class))), + @ApiResponse( + responseCode = "404", + description = "Tag not found", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @GetMapping("/{tagName}") + public Tag read( + @PathVariable("tagName") String tagName, + @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels) { + tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.FIND_TAG, tagName)); + + if (withChannels) { + Optional foundTag = tagRepository.findById(tagName, true); + if (foundTag.isPresent()) { + return foundTag.get(); + } else { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + Optional foundTag = tagRepository.findById(tagName); + if (foundTag.isPresent()) { + return foundTag.get(); + } else { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } } - - @Operation( - summary = "Get tag by name", - description = "Retrieve a tag by its name. Optionally include its channels.", - operationId = "getTagByName", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Finding Tag by tagName", - content = @Content(schema = @Schema(implementation = Tag.class))), - @ApiResponse( - responseCode = "404", - description = "Tag not found", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @GetMapping("/{tagName}") - public Tag read(@PathVariable("tagName") String tagName, - @RequestParam(value = "withChannels", defaultValue = "true") boolean withChannels) { - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.FIND_TAG, tagName)); - - if(withChannels) { - Optional foundTag = tagRepository.findById(tagName,true); - if(foundTag.isPresent()) { - return foundTag.get(); - } else { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - Optional foundTag = tagRepository.findById(tagName); - if(foundTag.isPresent()) { - return foundTag.get(); - } else { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + @Operation( + summary = "Create or update a tag", + description = "Create and exclusively update the tag identified by the path parameter.", + operationId = "createOrUpdateTag", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Tag created and updated", + content = @Content(schema = @Schema(implementation = Tag.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag-, or Channel-name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create/update Tag", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/{tagName}") + public Tag create(@PathVariable("tagName") String tagName, @RequestBody Tag tag) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + long start = System.currentTimeMillis(); + tagManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validateTagRequest(tag); + + // check if authorized owner + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), tag)) { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + Optional existingTag = tagRepository.findById(tagName); + boolean present = existingTag.isPresent(); + if (present) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + // delete existing tag + tagRepository.deleteById(tagName); + } + + // create new tag + Tag createdTag = tagRepository.index(tag); + + if (!tag.getChannels().isEmpty()) { + tag.getChannels().forEach(chan -> chan.addTag(createdTag)); + // update the listed channels in the tag's payloads with the new tag + Iterable chans = channelRepository.saveAll(tag.getChannels()); + List chanList = new ArrayList<>(); + for (Channel chan : chans) { + chanList.add(chan); } + createdTag.setChannels(chanList); + } + return createdTag; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Create or update a tag", - description = "Create and exclusively update the tag identified by the path parameter.", - operationId = "createOrUpdateTag", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tag created and updated", - content = @Content(schema = @Schema(implementation = Tag.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag-, or Channel-name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create/update Tag", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/{tagName}") - public Tag create(@PathVariable("tagName") String tagName, @RequestBody Tag tag) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - long start = System.currentTimeMillis(); - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validateTagRequest(tag); - - // check if authorized owner - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), tag)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - Optional existingTag = tagRepository.findById(tagName); - boolean present = existingTag.isPresent(); - if(present) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - // delete existing tag - tagRepository.deleteById(tagName); - } - - // create new tag - Tag createdTag = tagRepository.index(tag); - - if (!tag.getChannels().isEmpty()) { - tag.getChannels().forEach(chan -> chan.addTag(createdTag)); - // update the listed channels in the tag's payloads with the new tag - Iterable chans = channelRepository.saveAll(tag.getChannels()); - List chanList = new ArrayList<>(); - for (Channel chan : chans) { - chanList.add(chan); - } - createdTag.setChannels(chanList); - } - return createdTag; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + } + + @Operation( + summary = "Create multiple tags", + description = "Create multiple tags in a single request.", + operationId = "createMultipleTags", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Tags created", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag-, or Channel-name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while trying to create Tags", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping() + public Iterable create(@RequestBody Iterable tags) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + long start = System.currentTimeMillis(); + tagManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + + // check if authorized owner + for (Tag tag : tags) { + Optional existingTag = tagRepository.findById(tag.getName()); + boolean present = existingTag.isPresent(); + if (present) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + String message = + MessageFormat.format( + TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } - - @Operation( - summary = "Create multiple tags", - description = "Create multiple tags in a single request.", - operationId = "createMultipleTags", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tags created", - content = @Content( - array = - @ArraySchema(schema = @Schema(implementation = Tag.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag-, or Channel-name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while trying to create Tags", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping() - public Iterable create(@RequestBody Iterable tags) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - long start = System.currentTimeMillis(); - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - - // check if authorized owner - for(Tag tag: tags) { - Optional existingTag = tagRepository.findById(tag.getName()); - boolean present = existingTag.isPresent(); - if(present) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - tag.setOwner(existingTag.get().getOwner()); - } else { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), tag)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } - } - - // Validate request parameters - validateTagRequest(tags); - - // delete existing tags - for(Tag tag: tags) { - if(tagRepository.existsById(tag.getName())) { - // delete existing tag - tagRepository.deleteById(tag.getName()); - } - } - - // create new tags - Iterable createdTags = tagRepository.indexAll(Lists.newArrayList(tags)); - - // update the listed channels in the tags' payloads with new tags - Map channels = new HashMap<>(); - for (Tag tag : tags) { - for (Channel channel : tag.getChannels()) { - if (channels.get(channel.getName()) != null) { - channels.get(channel.getName()).addTag(new Tag(tag.getName(), tag.getOwner())); - } else { - channel.addTag(new Tag(tag.getName(), tag.getOwner())); - channels.put(channel.getName(), channel); - } - } - } - - if(!channels.isEmpty()) { - Iterable chans = channelRepository.saveAll(channels.values()); - } - // TODO should return created tags with properly organized saved channels, but it would be very complicated... - return tags; + } + tag.setOwner(existingTag.get().getOwner()); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAGS, tags); + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), tag)) { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } } - } + } - @Operation( - summary = "Add tag to a single channel", - description = "Add the tag identified by tagName to the channel identified by channelName.", - operationId = "addTagToChannel", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tags added to a single channel", - content = @Content(schema = @Schema(implementation = Tag.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag-, or Channel-name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Tag creational error", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/{tagName}/{channelName}") - public Tag addSingle(@PathVariable("tagName") String tagName, @PathVariable("channelName") String channelName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - long start = System.currentTimeMillis(); - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validateTagWithChannelRequest(channelName); - - // check if authorized owner - Optional existingTag = tagRepository.findById(tagName); - boolean present = existingTag.isPresent(); - if(present) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - // add tag to channel - Channel channel = channelRepository.findById(channelName).get(); - channel.addTag(existingTag.get()); - Channel taggedChannel = channelRepository.save(channel); - Tag addedTag = existingTag.get(); - addedTag.setChannels(Arrays.asList(taggedChannel)); - return addedTag; - } else { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + // Validate request parameters + validateTagRequest(tags); + + // delete existing tags + for (Tag tag : tags) { + if (tagRepository.existsById(tag.getName())) { + // delete existing tag + tagRepository.deleteById(tag.getName()); } + } + + // create new tags + Iterable createdTags = tagRepository.indexAll(Lists.newArrayList(tags)); + + // update the listed channels in the tags' payloads with new tags + Map channels = new HashMap<>(); + for (Tag tag : tags) { + for (Channel channel : tag.getChannels()) { + if (channels.get(channel.getName()) != null) { + channels.get(channel.getName()).addTag(new Tag(tag.getName(), tag.getOwner())); + } else { + channel.addTag(new Tag(tag.getName(), tag.getOwner())); + channels.put(channel.getName(), channel); + } + } + } + + if (!channels.isEmpty()) { + Iterable chans = channelRepository.saveAll(channels.values()); + } + // TODO should return created tags with properly organized saved channels, but it would be + // very complicated... + return tags; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAGS, tags); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Update a tag", - description = "Update the tag identified by the path parameter, adding it to all channels in the payload.", - operationId = "updateTag", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tag updated", - content = @Content(schema = @Schema(implementation = Tag.class))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Tag update error", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping("/{tagName}") - public Tag update(@PathVariable("tagName") String tagName, @RequestBody Tag tag) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - long start = System.currentTimeMillis(); - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - // Validate request parameters - validateTagRequest(tag); - - // check if authorized owner - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), tag)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - List channels = new ArrayList<>(); - Optional existingTag = tagRepository.findById(tagName,true); - - Tag newTag; - if(existingTag.isPresent()) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - channels = existingTag.get().getChannels(); - newTag = existingTag.get(); - newTag.setOwner(tag.getOwner()); - // Is an existing tag being renamed - if (!tag.getName().equalsIgnoreCase(existingTag.get().getName())) { - // Since this is a rename operation we will need to remove the old channel. - tagRepository.deleteById(existingTag.get().getName()); - newTag.setName(tag.getName()); - } - } else { - newTag = tag; - } - - // update tag - Tag updatedTag = tagRepository.save(newTag); - - // update channels of existing tag - if(!channels.isEmpty()) { - channels.forEach(chan -> chan.addTag(updatedTag)); - } - - // update the listed channels in the tag's payload with the updated tag - if(!tag.getChannels().isEmpty()) { - tag.getChannels().forEach(c -> c.addTag(updatedTag)); - // update the listed channels in the tag's payloads with the new tag - channels.addAll(tag.getChannels()); - } - - if(!channels.isEmpty()) { - Iterable updatedChannels = channelRepository.saveAll(channels); - updatedTag.setChannels(StreamSupport.stream(updatedChannels.spliterator(), false) - .collect(Collectors.toList())); - } - - return updatedTag; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + @Operation( + summary = "Add tag to a single channel", + description = "Add the tag identified by tagName to the channel identified by channelName.", + operationId = "addTagToChannel", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Tags added to a single channel", + content = @Content(schema = @Schema(implementation = Tag.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag-, or Channel-name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Tag creational error", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/{tagName}/{channelName}") + public Tag addSingle( + @PathVariable("tagName") String tagName, @PathVariable("channelName") String channelName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + long start = System.currentTimeMillis(); + tagManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validateTagWithChannelRequest(channelName); + + // check if authorized owner + Optional existingTag = tagRepository.findById(tagName); + boolean present = existingTag.isPresent(); + if (present) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + // add tag to channel + Channel channel = channelRepository.findById(channelName).get(); + channel.addTag(existingTag.get()); + Channel taggedChannel = channelRepository.save(channel); + Tag addedTag = existingTag.get(); + addedTag.setChannels(Arrays.asList(taggedChannel)); + return addedTag; + } else { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Update multiple tags", - description = "Update multiple tags and all appropriate channels. The operation will fail if any of the specified channels do not exist.", - operationId = "updateMultipleTags", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tags updated", - content = @Content(array = - @ArraySchema(schema = @Schema(implementation = Tag.class)))), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag-, or Channel-name does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Error while updating tags", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PostMapping() - public Iterable update(@RequestBody Iterable tags) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - long start = System.currentTimeMillis(); - tagManagerAudit.log(Level.INFO, () -> MessageFormat.format(TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); - - // check if authorized owner - for(Tag tag:tags) { - Optional existingTag = tagRepository.findById(tag.getName()); - boolean present = existingTag.isPresent(); - if(present) { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - tag.setOwner(existingTag.get().getOwner()); - } else { - if(!authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), tag)) { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } - } - - // Validate request parameters - validateTagRequest(tags); - - // update the listed channels in the tags' payloads with new tags - Map channels = new HashMap<>(); - for (Tag tag : tags) { - for (Channel channel : tag.getChannels()) { - if (channels.get(channel.getName()) != null) { - channels.get(channel.getName()).addTag(new Tag(tag.getName(), tag.getOwner())); - } else { - channel.addTag(new Tag(tag.getName(), tag.getOwner())); - channels.put(channel.getName(), channel); - } - } - } - - // update tags - Iterable updatedTags = tagRepository.saveAll(tags); - - // update channels - if(!channels.isEmpty()) { - channelRepository.saveAll(channels.values()); - } - // TODO should return updated tags with properly organized saved channels, but it would be very complicated... - return tags; - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAGS, tags); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + + @Operation( + summary = "Update a tag", + description = + "Update the tag identified by the path parameter, adding it to all channels in the payload.", + operationId = "updateTag", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Tag updated", + content = @Content(schema = @Schema(implementation = Tag.class))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Tag update error", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping("/{tagName}") + public Tag update(@PathVariable("tagName") String tagName, @RequestBody Tag tag) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + long start = System.currentTimeMillis(); + tagManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + // Validate request parameters + validateTagRequest(tag); + + // check if authorized owner + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), tag)) { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } + List channels = new ArrayList<>(); + Optional existingTag = tagRepository.findById(tagName, true); + + Tag newTag; + if (existingTag.isPresent()) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + String message = + MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + channels = existingTag.get().getChannels(); + newTag = existingTag.get(); + newTag.setOwner(tag.getOwner()); + // Is an existing tag being renamed + if (!tag.getName().equalsIgnoreCase(existingTag.get().getName())) { + // Since this is a rename operation we will need to remove the old channel. + tagRepository.deleteById(existingTag.get().getName()); + newTag.setName(tag.getName()); + } + } else { + newTag = tag; + } + + // update tag + Tag updatedTag = tagRepository.save(newTag); + + // update channels of existing tag + if (!channels.isEmpty()) { + channels.forEach(chan -> chan.addTag(updatedTag)); + } + + // update the listed channels in the tag's payload with the updated tag + if (!tag.getChannels().isEmpty()) { + tag.getChannels().forEach(c -> c.addTag(updatedTag)); + // update the listed channels in the tag's payloads with the new tag + channels.addAll(tag.getChannels()); + } + + if (!channels.isEmpty()) { + Iterable updatedChannels = channelRepository.saveAll(channels); + updatedTag.setChannels( + StreamSupport.stream(updatedChannels.spliterator(), false) + .collect(Collectors.toList())); + } + + return updatedTag; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - @Operation( - summary = "Delete a tag", - description = "Delete the tag identified by the path parameter from all channels.", - operationId = "deleteTag", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tag deleted"), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Tag creational error", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @DeleteMapping("/{tagName}") - public void remove(@PathVariable("tagName") String tagName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - Optional existingTag = tagRepository.findById(tagName); - if(existingTag.isPresent()) { - // check if authorized owner - if(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - // delete tag - tagRepository.deleteById(tagName); - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } else { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + } + + @Operation( + summary = "Update multiple tags", + description = + "Update multiple tags and all appropriate channels. The operation will fail if any of the specified channels do not exist.", + operationId = "updateMultipleTags", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Tags updated", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Tag.class)))), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag-, or Channel-name does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Error while updating tags", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PostMapping() + public Iterable update(@RequestBody Iterable tags) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + long start = System.currentTimeMillis(); + tagManagerAudit.log( + Level.INFO, + () -> + MessageFormat.format( + TextUtil.CLIENT_INITIALIZATION, (System.currentTimeMillis() - start))); + + // check if authorized owner + for (Tag tag : tags) { + Optional existingTag = tagRepository.findById(tag.getName()); + boolean present = existingTag.isPresent(); + if (present) { + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + String message = + MessageFormat.format( + TextUtil.USER_NOT_AUTHORIZED_ON_TAG, existingTag.get().toLog()); logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } - - @Operation( - summary = "Delete tag from a channel", - description = "Delete the tag identified by tagName from the channel identified by channelName.", - operationId = "deleteTagFromChannel", - tags = {"Tag"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Tag deleted from the desired channel"), - @ApiResponse( - responseCode = "400", - description = "Invalid request", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "404", - description = "Tag does not exist", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), - @ApiResponse( - responseCode = "500", - description = "Tag creational error", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @DeleteMapping("/{tagName}/{channelName}") - public void removeSingle(@PathVariable("tagName") final String tagName, @PathVariable("channelName") String channelName) { - // check if authorized role - if(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { - Optional existingTag = tagRepository.findById(tagName); - if(existingTag.isPresent()) { - // check if authorized owner - if(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { - Optional ch = channelRepository.findById(channelName); - if(ch.isPresent()) { - // remove tag from channel - Channel channel = ch.get(); - channel.removeTag(new Tag(tagName, "")); - channelRepository.index(channel); - } else { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } - } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); - } - } else { - String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + tag.setOwner(existingTag.get().getOwner()); } else { - String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + if (!authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), tag)) { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tag.toLog()); logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); + } } - } - - /** - * Checks if all the tags included satisfy the following conditions - * - *

    - *
  1. the tag names are not null or empty and matches the names in the bodies - *
  2. the tag owners are not null or empty - *
  3. all the channels exist - *
- * - * @param tags the list of tags to be validated - */ - public void validateTagRequest(Iterable tags) { - for(Tag tag: tags) { - validateTagRequest(tag); + } + + // Validate request parameters + validateTagRequest(tags); + + // update the listed channels in the tags' payloads with new tags + Map channels = new HashMap<>(); + for (Tag tag : tags) { + for (Channel channel : tag.getChannels()) { + if (channels.get(channel.getName()) != null) { + channels.get(channel.getName()).addTag(new Tag(tag.getName(), tag.getOwner())); + } else { + channel.addTag(new Tag(tag.getName(), tag.getOwner())); + channels.put(channel.getName(), channel); + } } + } + + // update tags + Iterable updatedTags = tagRepository.saveAll(tags); + + // update channels + if (!channels.isEmpty()) { + channelRepository.saveAll(channels.values()); + } + // TODO should return updated tags with properly organized saved channels, but it would be + // very complicated... + return tags; + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAGS, tags); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - /** - * Checks if tag satisfies the following conditions - * - *
    - *
  1. the tag name is not null or empty and matches the name in the body - *
  2. the tag owner is not null or empty - *
  3. all the listed channels exist - *
- * - * @param tag the tag to be validates - */ - public void validateTagRequest(Tag tag) { - // 1 - if (tag.getName() == null || tag.getName().isEmpty()) { - String message = MessageFormat.format(TextUtil.TAG_NAME_CANNOT_BE_NULL_OR_EMPTY, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); - } - // 2 - if (tag.getOwner() == null || tag.getOwner().isEmpty()) { - String message = MessageFormat.format(TextUtil.TAG_OWNER_CANNOT_BE_NULL_OR_EMPTY, tag.toLog()); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); - } - // 3 - List channelNames = tag.getChannels().stream().map(Channel::getName).collect(Collectors.toList()); - for(String channelName:channelNames) { - if(!channelRepository.existsById(channelName)) { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); - logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); - throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); - } + } + + @Operation( + summary = "Delete a tag", + description = "Delete the tag identified by the path parameter from all channels.", + operationId = "deleteTag", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Tag deleted"), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Tag creational error", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @DeleteMapping("/{tagName}") + public void remove(@PathVariable("tagName") String tagName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + Optional existingTag = tagRepository.findById(tagName); + if (existingTag.isPresent()) { + // check if authorized owner + if (authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + // delete tag + tagRepository.deleteById(tagName); + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } else { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - - /** - * Checks if channel with name "channelName" exists - * @param channelName check channel exists - */ - public void validateTagWithChannelRequest(String channelName) { - if(!channelRepository.existsById(channelName)) { - String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + } + + @Operation( + summary = "Delete tag from a channel", + description = + "Delete the tag identified by tagName from the channel identified by channelName.", + operationId = "deleteTagFromChannel", + tags = {"Tag"}) + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Tag deleted from the desired channel"), + @ApiResponse( + responseCode = "400", + description = "Invalid request", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "404", + description = "Tag does not exist", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))), + @ApiResponse( + responseCode = "500", + description = "Tag creational error", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @DeleteMapping("/{tagName}/{channelName}") + public void removeSingle( + @PathVariable("tagName") final String tagName, + @PathVariable("channelName") String channelName) { + // check if authorized role + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG)) { + Optional existingTag = tagRepository.findById(tagName); + if (existingTag.isPresent()) { + // check if authorized owner + if (authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), existingTag.get())) { + Optional ch = channelRepository.findById(channelName); + if (ch.isPresent()) { + // remove tag from channel + Channel channel = ch.get(); + channel.removeTag(new Tag(tagName, "")); + channelRepository.index(channel); + } else { + String message = + MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } + } else { + String message = MessageFormat.format(TextUtil.TAG_NAME_DOES_NOT_EXIST, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } else { + String message = MessageFormat.format(TextUtil.USER_NOT_AUTHORIZED_ON_TAG, tagName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, message, null); } - + } + + /** + * Checks if all the tags included satisfy the following conditions + * + *
    + *
  1. the tag names are not null or empty and matches the names in the bodies + *
  2. the tag owners are not null or empty + *
  3. all the channels exist + *
+ * + * @param tags the list of tags to be validated + */ + public void validateTagRequest(Iterable tags) { + for (Tag tag : tags) { + validateTagRequest(tag); + } + } + + /** + * Checks if tag satisfies the following conditions + * + *
    + *
  1. the tag name is not null or empty and matches the name in the body + *
  2. the tag owner is not null or empty + *
  3. all the listed channels exist + *
+ * + * @param tag the tag to be validates + */ + public void validateTagRequest(Tag tag) { + // 1 + if (tag.getName() == null || tag.getName().isEmpty()) { + String message = MessageFormat.format(TextUtil.TAG_NAME_CANNOT_BE_NULL_OR_EMPTY, tag.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); + } + // 2 + if (tag.getOwner() == null || tag.getOwner().isEmpty()) { + String message = + MessageFormat.format(TextUtil.TAG_OWNER_CANNOT_BE_NULL_OR_EMPTY, tag.toLog()); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.BAD_REQUEST)); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message, null); + } + // 3 + List channelNames = + tag.getChannels().stream().map(Channel::getName).collect(Collectors.toList()); + for (String channelName : channelNames) { + if (!channelRepository.existsById(channelName)) { + String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } + } + + /** + * Checks if channel with name "channelName" exists + * + * @param channelName check channel exists + */ + public void validateTagWithChannelRequest(String channelName) { + if (!channelRepository.existsById(channelName)) { + String message = MessageFormat.format(TextUtil.CHANNEL_NAME_DOES_NOT_EXIST, channelName); + logger.log(Level.SEVERE, message, new ResponseStatusException(HttpStatus.NOT_FOUND)); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, message); + } + } } diff --git a/src/main/java/org/phoebus/channelfinder/TagRepository.java b/src/main/java/org/phoebus/channelfinder/TagRepository.java index d6683e0b..46c0e39f 100644 --- a/src/main/java/org/phoebus/channelfinder/TagRepository.java +++ b/src/main/java/org/phoebus/channelfinder/TagRepository.java @@ -1,20 +1,13 @@ package org.phoebus.channelfinder; -import java.io.IOException; -import java.text.MessageFormat; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.StreamSupport; - +import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.ElasticsearchException; import co.elastic.clients.elasticsearch._types.FieldSort; import co.elastic.clients.elasticsearch._types.Refresh; import co.elastic.clients.elasticsearch._types.Result; import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.query_dsl.IdsQuery; +import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery; import co.elastic.clients.elasticsearch.core.BulkRequest; import co.elastic.clients.elasticsearch.core.BulkResponse; import co.elastic.clients.elasticsearch.core.CountRequest; @@ -24,10 +17,21 @@ import co.elastic.clients.elasticsearch.core.GetResponse; import co.elastic.clients.elasticsearch.core.IndexResponse; import co.elastic.clients.elasticsearch.core.SearchRequest; +import co.elastic.clients.elasticsearch.core.SearchRequest.Builder; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; +import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.JsonData; import co.elastic.clients.json.jackson.JacksonJsonpMapper; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.StreamSupport; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Tag; import org.phoebus.channelfinder.entity.Tag.OnlyTag; @@ -41,356 +45,359 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import co.elastic.clients.elasticsearch.ElasticsearchClient; -import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery; -import co.elastic.clients.elasticsearch.core.SearchRequest.Builder; -import co.elastic.clients.elasticsearch.core.search.Hit; - @Repository @Configuration public class TagRepository implements CrudRepository { - private static final Logger logger = Logger.getLogger(TagRepository.class.getName()); - - @Autowired - ElasticConfig esService; - - @Autowired - @Qualifier("indexClient") - ElasticsearchClient client; - - @Autowired - ChannelRepository channelRepository; - - ObjectMapper objectMapper = new ObjectMapper().addMixIn(Tag.class, OnlyTag.class); - - /** - * create a new tag using the given Tag - * - * @param extends Tag - * @param tag - tag to be created - * @return the created tag - */ - public S index(S tag) { - return save(tag.getName(), tag); + private static final Logger logger = Logger.getLogger(TagRepository.class.getName()); + + @Autowired ElasticConfig esService; + + @Autowired + @Qualifier("indexClient") + ElasticsearchClient client; + + @Autowired ChannelRepository channelRepository; + + ObjectMapper objectMapper = new ObjectMapper().addMixIn(Tag.class, OnlyTag.class); + + /** + * create a new tag using the given Tag + * + * @param extends Tag + * @param tag - tag to be created + * @return the created tag + */ + public S index(S tag) { + return save(tag.getName(), tag); + } + + /** + * create new tags using the given XmlTags + * + * @param tags - tags to be created + * @return the created tags + */ + public List indexAll(List tags) { + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Tag tag : tags) { + br.operations( + op -> + op.index( + idx -> + idx.index(esService.getES_TAG_INDEX()) + .id(tag.getName()) + .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))))); } - - /** - * create new tags using the given XmlTags - * - * @param tags - tags to be created - * @return the created tags - */ - public List indexAll(List tags) { - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Tag tag : tags) { - br.operations(op -> op - .index(idx -> idx - .index(esService.getES_TAG_INDEX()) - .id(tag.getName()) - .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))))); - } - try { - BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - // TODO cleanup? or throw exception? - } else { - return findAllById(tags.stream().map(Tag::getName).toList()); - } - } 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); + try { + BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - return Collections.emptyList(); + // TODO cleanup? or throw exception? + } else { + return findAllById(tags.stream().map(Tag::getName).toList()); + } + } 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); } - - /** - * update/save tag using the given Tag - * - * @param extends Tag - * @param tagName - name of tag to be created - * @param tag - tag to be created - * @return the updated/saved tag - */ - @SuppressWarnings("unchecked") - public S save(String tagName, S tag) { - try{ - IndexResponse response = client - .index(i -> i.index(esService.getES_TAG_INDEX()) - .id(tagName) - .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))) - .refresh(Refresh.True)); - // verify the creation of the tag - if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_TAG, tag.toLog())); - return (S) findById(tagName).get(); - } - } 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); - } - return null; + return Collections.emptyList(); + } + + /** + * update/save tag using the given Tag + * + * @param extends Tag + * @param tagName - name of tag to be created + * @param tag - tag to be created + * @return the updated/saved tag + */ + @SuppressWarnings("unchecked") + public S save(String tagName, S tag) { + try { + IndexResponse response = + client.index( + i -> + i.index(esService.getES_TAG_INDEX()) + .id(tagName) + .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))) + .refresh(Refresh.True)); + // verify the creation of the tag + if (response.result().equals(Result.Created) || response.result().equals(Result.Updated)) { + logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.CREATE_TAG, tag.toLog())); + return (S) findById(tagName).get(); + } + } 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); } - - @Override - public S save(S tag) { - return save(tag.getName(), tag); + return null; + } + + @Override + public S save(S tag) { + return save(tag.getName(), tag); + } + + /** + * update/save tags using the given XmlTags + * + * @param extends Tag + * @param tags - tags to be created + * @return the updated/saved tags + */ + @SuppressWarnings("unchecked") + @Override + public Iterable saveAll(Iterable tags) { + + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Tag tag : tags) { + br.operations( + op -> + op.index( + idx -> + idx.index(esService.getES_TAG_INDEX()) + .id(tag.getName()) + .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))))); } - /** - * update/save tags using the given XmlTags - * - * @param extends Tag - * @param tags - tags to be created - * @return the updated/saved tags - */ - @SuppressWarnings("unchecked") - @Override - public Iterable saveAll(Iterable tags) { - - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Tag tag : tags) { - br.operations(op -> op - .index(idx -> idx - .index(esService.getES_TAG_INDEX()) - .id(tag.getName()) - .document(JsonData.of(tag, new JacksonJsonpMapper(objectMapper))) - ) - ); + BulkResponse result = null; + try { + result = client.bulk(br.refresh(Refresh.True).build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - - BulkResponse result = null; - try { - result = client.bulk(br.refresh(Refresh.True).build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - // TODO cleanup? or throw exception? - } else { - return (Iterable) findAllById( - StreamSupport.stream(tags.spliterator(), false) - .map(Tag::getName) - .toList()); - } - } 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); - - } - return null; - } - - /** - * find tag using the given tag id - * - * @param tagId - id of tag to be found - * @return the found tag - */ - @Override - public Optional findById(String tagId) { - return findById(tagId, false); + // TODO cleanup? or throw exception? + } else { + return (Iterable) + findAllById(StreamSupport.stream(tags.spliterator(), false).map(Tag::getName).toList()); + } + } 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); } - - /** - * find tag using the given tag id - * - * @param tagId - id of tag to be found - * @param withChannels - whether channels should be included - * @return the found tag - */ - public Optional findById(String tagId, boolean withChannels) { - GetResponse response; - try { - response = client.get(g -> g.index(esService.getES_TAG_INDEX()).id(tagId), Tag.class); - - if (response.found()) { - 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()); - } - return Optional.of(tag); - } else { - logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.TAG_NOT_FOUND, tagId)); - return Optional.empty(); - } - } 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); + return null; + } + + /** + * find tag using the given tag id + * + * @param tagId - id of tag to be found + * @return the found tag + */ + @Override + public Optional findById(String tagId) { + return findById(tagId, false); + } + + /** + * find tag using the given tag id + * + * @param tagId - id of tag to be found + * @param withChannels - whether channels should be included + * @return the found tag + */ + public Optional findById(String tagId, boolean withChannels) { + GetResponse response; + try { + response = client.get(g -> g.index(esService.getES_TAG_INDEX()).id(tagId), Tag.class); + + if (response.found()) { + 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()); } + return Optional.of(tag); + } else { + logger.log(Level.CONFIG, () -> MessageFormat.format(TextUtil.TAG_NOT_FOUND, tagId)); + return Optional.empty(); + } + } 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); } - - @Override - public boolean existsById(String id) { - try { - ExistsRequest.Builder builder = new ExistsRequest.Builder(); - builder.index(esService.getES_TAG_INDEX()).id(id); - return client.exists(builder.build()).value(); - } 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); - } + } + + @Override + public boolean existsById(String id) { + try { + ExistsRequest.Builder builder = new ExistsRequest.Builder(); + builder.index(esService.getES_TAG_INDEX()).id(id); + return client.exists(builder.build()).value(); + } 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); } - - /** - * find all tags - * - * @return the found tags - */ - @Override - public Iterable findAll() { - try { - SearchRequest.Builder searchBuilder = new Builder() - .index(esService.getES_TAG_INDEX()) - .query(new MatchAllQuery.Builder().build()._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Tag.class); - 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); - } + } + + /** + * find all tags + * + * @return the found tags + */ + @Override + public Iterable findAll() { + try { + SearchRequest.Builder searchBuilder = + new Builder() + .index(esService.getES_TAG_INDEX()) + .query(new MatchAllQuery.Builder().build()._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Tag.class); + 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); } - - /** - * find tags using the given tags ids - * - * @param tagIds - ids of tags to be found - * @return the found tags - */ - @Override - public List findAllById(Iterable tagIds) { - try { - List ids = StreamSupport.stream(tagIds.spliterator(), false).toList(); - SearchRequest.Builder searchBuilder = new Builder() - .index(esService.getES_TAG_INDEX()) - .query(IdsQuery.of(q -> q.values(ids))._toQuery()) - .size(esService.getES_QUERY_SIZE()) - .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); - SearchResponse response = client.search(searchBuilder.build(), Tag.class); - 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); - } + } + + /** + * find tags using the given tags ids + * + * @param tagIds - ids of tags to be found + * @return the found tags + */ + @Override + public List findAllById(Iterable tagIds) { + try { + List ids = StreamSupport.stream(tagIds.spliterator(), false).toList(); + SearchRequest.Builder searchBuilder = + new Builder() + .index(esService.getES_TAG_INDEX()) + .query(IdsQuery.of(q -> q.values(ids))._toQuery()) + .size(esService.getES_QUERY_SIZE()) + .sort(SortOptions.of(s -> s.field(FieldSort.of(f -> f.field("name"))))); + SearchResponse response = client.search(searchBuilder.build(), Tag.class); + 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); } - - @Override - public long count() { - try { - CountRequest countRequest = new CountRequest.Builder().index(esService.getES_TAG_INDEX()).build(); - CountResponse countResponse = client.count(countRequest); - return countResponse.count(); - } catch (ElasticsearchException | IOException e) { - - 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); - } + } + + @Override + public long count() { + try { + CountRequest countRequest = + new CountRequest.Builder().index(esService.getES_TAG_INDEX()).build(); + CountResponse countResponse = client.count(countRequest); + return countResponse.count(); + } catch (ElasticsearchException | IOException e) { + + 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); } - - /** - * delete the given tag by tag name - * - * @param tagName - tag to be deleted - */ - @Override - public void deleteById(String tagName) { + } + + /** + * delete the given tag by tag name + * + * @param tagName - tag to be deleted + */ + @Override + public void deleteById(String tagName) { + try { + + DeleteResponse response = + client.delete( + i -> i.index(esService.getES_TAG_INDEX()).id(tagName).refresh(Refresh.True)); + // verify the deletion of the tag + if (response.result().equals(Result.Deleted)) { + 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); + List channels = channelRepository.search(params).channels(); + while (!channels.isEmpty()) { + + for (Channel channel : channels) { + // Or + channel.removeTag( + channel.getTags().stream() + .filter(tag -> tagName.equalsIgnoreCase(tag.getName())) + .findAny() + .get()); + br.operations( + op -> + op.update( + u -> + u.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .action(a -> a.doc(channel)))); + } try { - - DeleteResponse response = client - .delete(i -> i.index(esService.getES_TAG_INDEX()).id(tagName).refresh(Refresh.True)); - // verify the deletion of the tag - if (response.result().equals(Result.Deleted)) { - 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); - List channels = channelRepository.search(params).channels(); - while (!channels.isEmpty()) { - - for (Channel channel : channels) { - // Or - channel.removeTag(channel.getTags().stream().filter(tag -> tagName.equalsIgnoreCase(tag.getName())).findAny().get()); - br.operations(op -> op.update( - u -> u.index(esService.getES_CHANNEL_INDEX()) - .id(channel.getName()) - .action(a -> a.doc(channel)))); - } - try { - BulkResponse result = client.bulk(br.build()); - // Log errors, if any - if (result.errors()) { - logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } - } 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); - - } - params.set("~search_after", channels.get(channels.size() - 1).getName()); - channels = channelRepository.search(params).channels(); + BulkResponse result = client.bulk(br.build()); + // Log errors, if any + if (result.errors()) { + logger.log(Level.SEVERE, TextUtil.BULK_HAD_ERRORS); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } - - } 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); + } + } 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); } + params.set("~search_after", channels.get(channels.size() - 1).getName()); + channels = channelRepository.search(params).channels(); + } + + } 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); } - - /** - * delete the given tag - * - * @param tag - tag to be deleted - */ - @Override - public void delete(Tag tag) { - deleteById(tag.getName()); - } - - @Override - public void deleteAll(Iterable entities) { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - - @Override - public void deleteAll() { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - - @Override - public void deleteAllById(Iterable ids) { - throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); - } - + } + + /** + * delete the given tag + * + * @param tag - tag to be deleted + */ + @Override + public void delete(Tag tag) { + deleteById(tag.getName()); + } + + @Override + public void deleteAll(Iterable entities) { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } + + @Override + public void deleteAll() { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } + + @Override + public void deleteAllById(Iterable ids) { + throw new UnsupportedOperationException(TextUtil.DELETE_ALL_NOT_SUPPORTED); + } } diff --git a/src/main/java/org/phoebus/channelfinder/TextUtil.java b/src/main/java/org/phoebus/channelfinder/TextUtil.java index 71761cf7..a73d8de1 100644 --- a/src/main/java/org/phoebus/channelfinder/TextUtil.java +++ b/src/main/java/org/phoebus/channelfinder/TextUtil.java @@ -2,108 +2,126 @@ /** * Utility class to assist in handling of text. - * + * * @author Lars Johansson */ public class TextUtil { - // common - // channel - // property - // scroll - // tag - - public static final String CLIENT_INITIALIZATION = "Client initialization {0}"; - public static final String PATH_POST_VALIDATION_TIME = "|{0} |POST|validation {1}"; - public static final String PATH_POST_PREPERATION_TIME = "|{0} |POST|prepare {1}"; - - public static final String COUNT_FAILED_CAUSE = "Count failed for {0} Cause {1}"; - public static final String SEARCH_FAILED_CAUSE = "Search failed for {0} Cause {1}"; - public static final String PAYLOAD_PROPERTY_DOES_NOT_MATCH_URI_OR_HAS_BAD_VALUE = "The payload property {0} does not match uri name or has a bad value"; - - public static final String BULK_HAD_ERRORS = "Bulk had errors"; - public static final String CREATED_INDEX_ACKNOWLEDGED = "Created index {0} acknowledged {1}"; - public static final String UPDATE_INDEX_ACKNOWLEDGED = "Updated index {0} acknowledged {1}"; - public static final String DELETE_ALL_NOT_SUPPORTED = "Delete all is not supported."; - public static final String FAILED_TO_CREATE_INDEX = "Failed to create index {0}"; - - // ---------------------------------------------------------------------------------------------------- - - public static final String CHANNEL_FOUND = "Channel found {0}"; - public static final String CHANNEL_NOT_FOUND = "Channel not found {0}"; - public static final String CHANNEL_NAME_DOES_NOT_EXIST = "The channel with the name {0} does not exist"; - public static final String CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY = "The channel name cannot be null or empty {0}"; - public static final String CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY = "The channel owner cannot be null or empty {0}"; - public static final String CHANNEL_NAME_NO_VALID_INSTANCE_PROPERTY = "The channel with the name {0} does not include a valid instance to the property {1}"; - - public static final String CREATE_CHANNEL = "Create channel {0}"; - public static final String CREATE_PROPERTY = "Create property {0}"; - public static final String CREATE_TAG = "Create tag {0}"; - - public static final String DELETE_CHANNEL = "Delete channel {0}"; - public static final String DELETE_PROPERTY = "Delete property {0}"; - public static final String DELETE_TAG = "Delete tag {0}"; - - public static final String FIND_ALL_CHANNELS_NOT_SUPPORTED = "Find all is not supported. It could return hundreds of thousands of channels."; - public static final String FIND_CHANNEL = "Find channel {0}"; - - public static final String FAILED_TO_INDEX_CHANNEL = "Failed to index channel {0}"; - public static final String FAILED_TO_INDEX_CHANNELS = "Failed to index channels {0}"; - public static final String FAILED_TO_FIND_CHANNEL = "Failed to find channel {0}"; - public static final String FAILED_TO_FIND_ALL_CHANNELS = "Failed to find all channels"; - public static final String FAILED_TO_CHECK_IF_CHANNEL_EXISTS = "Failed to check if channel exists {0}"; - public static final String FAILED_TO_DELETE_CHANNEL = "Failed to delete channel {0}"; - - public static final String USER_NOT_AUTHORIZED_ON_CHANNEL = "User does not have the proper authorization to perform an operation on this channel {0}"; - public static final String USER_NOT_AUTHORIZED_ON_CHANNELS = "User does not have the proper authorization to perform an operation on these channels {0}"; - - // ---------------------------------------------------------------------------------------------------- - - public static final String PROPERTY_FOUND = "Property found {0}"; - public static final String PROPERTY_NOT_FOUND = "Property not found {0}"; - public static final String PROPERTY_NAME_DOES_NOT_EXIST = "The property with the name {0} does not exist"; - public static final String PROPERTY_NAME_CANNOT_BE_NULL_OR_EMPTY = "The property name cannot be null or empty {0}"; - public static final String PROPERTY_OWNER_CANNOT_BE_NULL_OR_EMPTY = "The property owner cannot be null or empty {0}"; - public static final String PROPERTY_VALUE_NULL_OR_EMPTY = "The property with the name {0} has value {1} is null or empty"; - - public static final String FIND_PROPERTY = "Find property {0}"; - - public static final String FAILED_TO_INDEX_PROPERTY = "Failed to index property {0}"; - public static final String FAILED_TO_INDEX_PROPERTIES = "Failed to index properties {0}"; - public static final String FAILED_TO_UPDATE_SAVE_PROPERTIES = "Failed to update/save properties {0}"; - public static final String FAILED_TO_FIND_PROPERTY = "Failed to find property {0}"; - public static final String FAILED_TO_FIND_ALL_PROPERTIES = "Failed to find all properties"; - public static final String FAILED_TO_CHECK_IF_PROPERTY_EXISTS = "Failed to check if property exists {0}"; - public static final String FAILED_TO_DELETE_PROPERTY = "Failed to delete property {0}"; - - public static final String USER_NOT_AUTHORIZED_ON_PROPERTY = "User does not have the proper authorization to perform an operation on this property {0}"; - public static final String USER_NOT_AUTHORIZED_ON_PROPERTIES = "User does not have the proper authorization to perform an operation on these properties {0}"; - - // ---------------------------------------------------------------------------------------------------- - - public static final String TAG_FOUND = "Tag found {0}"; - public static final String TAG_NOT_FOUND = "Tag not found {0}"; - public static final String TAG_NAME_DOES_NOT_EXIST = "The tag with the name {0} does not exist"; - public static final String TAG_NAME_CANNOT_BE_NULL_OR_EMPTY = "The tag name cannot be null or empty {0}"; - public static final String TAG_OWNER_CANNOT_BE_NULL_OR_EMPTY = "The tag owner cannot be null or empty {0}"; - - public static final String FIND_TAG = "Find tag {0}"; - - public static final String FAILED_TO_INDEX_TAGS = "Failed to index tags {0}"; - public static final String FAILED_TO_UPDATE_SAVE_TAG = "Failed to update/save tag {0}"; - public static final String FAILED_TO_FIND_TAG = "Failed to find tag {0}"; - public static final String FAILED_TO_FIND_ALL_TAGS = "Failed to find all tags"; - public static final String FAILED_TO_CHECK_IF_TAG_EXISTS = "Failed to check if tag exists {0}"; - public static final String FAILED_TO_DELETE_TAG = "Failed to delete tag {0}"; - - public static final String USER_NOT_AUTHORIZED_ON_TAG = "User does not have the proper authorization to perform an operation on this tag {0}"; - public static final String USER_NOT_AUTHORIZED_ON_TAGS = "User does not have the proper authorization to perform an operation on these tags {0}"; - - /** - * This class is not to be instantiated. - */ - private TextUtil() { - throw new IllegalStateException("Utility class"); - } - + // common + // channel + // property + // scroll + // tag + + public static final String CLIENT_INITIALIZATION = "Client initialization {0}"; + public static final String PATH_POST_VALIDATION_TIME = "|{0} |POST|validation {1}"; + public static final String PATH_POST_PREPERATION_TIME = "|{0} |POST|prepare {1}"; + + public static final String COUNT_FAILED_CAUSE = "Count failed for {0} Cause {1}"; + public static final String SEARCH_FAILED_CAUSE = "Search failed for {0} Cause {1}"; + public static final String PAYLOAD_PROPERTY_DOES_NOT_MATCH_URI_OR_HAS_BAD_VALUE = + "The payload property {0} does not match uri name or has a bad value"; + + public static final String BULK_HAD_ERRORS = "Bulk had errors"; + public static final String CREATED_INDEX_ACKNOWLEDGED = "Created index {0} acknowledged {1}"; + public static final String UPDATE_INDEX_ACKNOWLEDGED = "Updated index {0} acknowledged {1}"; + public static final String DELETE_ALL_NOT_SUPPORTED = "Delete all is not supported."; + public static final String FAILED_TO_CREATE_INDEX = "Failed to create index {0}"; + + // ---------------------------------------------------------------------------------------------------- + + public static final String CHANNEL_FOUND = "Channel found {0}"; + public static final String CHANNEL_NOT_FOUND = "Channel not found {0}"; + public static final String CHANNEL_NAME_DOES_NOT_EXIST = + "The channel with the name {0} does not exist"; + public static final String CHANNEL_NAME_CANNOT_BE_NULL_OR_EMPTY = + "The channel name cannot be null or empty {0}"; + public static final String CHANNEL_OWNER_CANNOT_BE_NULL_OR_EMPTY = + "The channel owner cannot be null or empty {0}"; + public static final String CHANNEL_NAME_NO_VALID_INSTANCE_PROPERTY = + "The channel with the name {0} does not include a valid instance to the property {1}"; + + public static final String CREATE_CHANNEL = "Create channel {0}"; + public static final String CREATE_PROPERTY = "Create property {0}"; + public static final String CREATE_TAG = "Create tag {0}"; + + public static final String DELETE_CHANNEL = "Delete channel {0}"; + public static final String DELETE_PROPERTY = "Delete property {0}"; + public static final String DELETE_TAG = "Delete tag {0}"; + + public static final String FIND_ALL_CHANNELS_NOT_SUPPORTED = + "Find all is not supported. It could return hundreds of thousands of channels."; + public static final String FIND_CHANNEL = "Find channel {0}"; + + public static final String FAILED_TO_INDEX_CHANNEL = "Failed to index channel {0}"; + public static final String FAILED_TO_INDEX_CHANNELS = "Failed to index channels {0}"; + public static final String FAILED_TO_FIND_CHANNEL = "Failed to find channel {0}"; + public static final String FAILED_TO_FIND_ALL_CHANNELS = "Failed to find all channels"; + public static final String FAILED_TO_CHECK_IF_CHANNEL_EXISTS = + "Failed to check if channel exists {0}"; + public static final String FAILED_TO_DELETE_CHANNEL = "Failed to delete channel {0}"; + + public static final String USER_NOT_AUTHORIZED_ON_CHANNEL = + "User does not have the proper authorization to perform an operation on this channel {0}"; + public static final String USER_NOT_AUTHORIZED_ON_CHANNELS = + "User does not have the proper authorization to perform an operation on these channels {0}"; + + // ---------------------------------------------------------------------------------------------------- + + public static final String PROPERTY_FOUND = "Property found {0}"; + public static final String PROPERTY_NOT_FOUND = "Property not found {0}"; + public static final String PROPERTY_NAME_DOES_NOT_EXIST = + "The property with the name {0} does not exist"; + public static final String PROPERTY_NAME_CANNOT_BE_NULL_OR_EMPTY = + "The property name cannot be null or empty {0}"; + public static final String PROPERTY_OWNER_CANNOT_BE_NULL_OR_EMPTY = + "The property owner cannot be null or empty {0}"; + public static final String PROPERTY_VALUE_NULL_OR_EMPTY = + "The property with the name {0} has value {1} is null or empty"; + + public static final String FIND_PROPERTY = "Find property {0}"; + + public static final String FAILED_TO_INDEX_PROPERTY = "Failed to index property {0}"; + public static final String FAILED_TO_INDEX_PROPERTIES = "Failed to index properties {0}"; + public static final String FAILED_TO_UPDATE_SAVE_PROPERTIES = + "Failed to update/save properties {0}"; + public static final String FAILED_TO_FIND_PROPERTY = "Failed to find property {0}"; + public static final String FAILED_TO_FIND_ALL_PROPERTIES = "Failed to find all properties"; + public static final String FAILED_TO_CHECK_IF_PROPERTY_EXISTS = + "Failed to check if property exists {0}"; + public static final String FAILED_TO_DELETE_PROPERTY = "Failed to delete property {0}"; + + public static final String USER_NOT_AUTHORIZED_ON_PROPERTY = + "User does not have the proper authorization to perform an operation on this property {0}"; + public static final String USER_NOT_AUTHORIZED_ON_PROPERTIES = + "User does not have the proper authorization to perform an operation on these properties {0}"; + + // ---------------------------------------------------------------------------------------------------- + + public static final String TAG_FOUND = "Tag found {0}"; + public static final String TAG_NOT_FOUND = "Tag not found {0}"; + public static final String TAG_NAME_DOES_NOT_EXIST = "The tag with the name {0} does not exist"; + public static final String TAG_NAME_CANNOT_BE_NULL_OR_EMPTY = + "The tag name cannot be null or empty {0}"; + public static final String TAG_OWNER_CANNOT_BE_NULL_OR_EMPTY = + "The tag owner cannot be null or empty {0}"; + + public static final String FIND_TAG = "Find tag {0}"; + + public static final String FAILED_TO_INDEX_TAGS = "Failed to index tags {0}"; + public static final String FAILED_TO_UPDATE_SAVE_TAG = "Failed to update/save tag {0}"; + public static final String FAILED_TO_FIND_TAG = "Failed to find tag {0}"; + public static final String FAILED_TO_FIND_ALL_TAGS = "Failed to find all tags"; + public static final String FAILED_TO_CHECK_IF_TAG_EXISTS = "Failed to check if tag exists {0}"; + public static final String FAILED_TO_DELETE_TAG = "Failed to delete tag {0}"; + + public static final String USER_NOT_AUTHORIZED_ON_TAG = + "User does not have the proper authorization to perform an operation on this tag {0}"; + public static final String USER_NOT_AUTHORIZED_ON_TAGS = + "User does not have the proper authorization to perform an operation on these tags {0}"; + + /** This class is not to be instantiated. */ + private TextUtil() { + throw new IllegalStateException("Utility class"); + } } diff --git a/src/main/java/org/phoebus/channelfinder/WebSecurityConfig.java b/src/main/java/org/phoebus/channelfinder/WebSecurityConfig.java index f4506bd2..b9868c33 100644 --- a/src/main/java/org/phoebus/channelfinder/WebSecurityConfig.java +++ b/src/main/java/org/phoebus/channelfinder/WebSecurityConfig.java @@ -17,132 +17,137 @@ @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().disable(); - http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - http.authorizeRequests().anyRequest().authenticated(); - http.httpBasic(); - } + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable(); + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + http.authorizeRequests().anyRequest().authenticated(); + http.httpBasic(); + } - @Override - public void configure(WebSecurity web) throws Exception { - // Authentication and Authorization is only needed for non search/query operations - web.ignoring().antMatchers(HttpMethod.GET, "/**"); - } + @Override + public void configure(WebSecurity web) throws Exception { + // Authentication and Authorization is only needed for non search/query operations + web.ignoring().antMatchers(HttpMethod.GET, "/**"); + } - /** - * External LDAP configuration properties - */ - @Value("${ldap.enabled:false}") - boolean ldap_enabled; - @Value("${ldap.urls:ldaps://localhost:389/}") - String ldap_url; - @Value("${ldap.user.dn.pattern}") - String ldap_user_dn_pattern; - @Value("${ldap.groups.search.base}") - String ldap_groups_search_base; - @Value("${ldap.groups.search.pattern}") - String ldap_groups_search_pattern; - - /** - * Embedded LDAP configuration properties - */ - @Value("${embedded_ldap.enabled:false}") - boolean embedded_ldap_enabled; - @Value("${embedded_ldap.urls:ldaps://localhost:389/}") - String embedded_ldap_url; - @Value("${embedded_ldap.user.dn.pattern}") - String embedded_ldap_user_dn_pattern; - @Value("${embedded_ldap.groups.search.base}") - String embedded_ldap_groups_search_base; - @Value("${embedded_ldap.groups.search.pattern}") - String embedded_ldap_groups_search_pattern; - - /** - * Demo authorization based on in memory user credentials - */ - @Value("${demo_auth.enabled:false}") - boolean demo_auth_enabled; - @Value("${demo_auth.delimiter.roles::}") - String demo_auth_delimiter_roles; - @Value("${demo_auth.users}") - String[] demo_auth_users; - @Value("${demo_auth.pwds}") - String[] demo_auth_pwds; - @Value("${demo_auth.roles}") - String[] demo_auth_roles; - - /** - * File based authentication - */ - @Value("${file.auth.enabled:true}") - boolean file_enabled; - - @Override - public void configure(AuthenticationManagerBuilder auth) throws Exception { - - if (ldap_enabled) { - DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldap_url); - contextSource.afterPropertiesSet(); - - DefaultLdapAuthoritiesPopulator myAuthPopulator = new DefaultLdapAuthoritiesPopulator(contextSource, ldap_groups_search_base); - myAuthPopulator.setGroupSearchFilter(ldap_groups_search_pattern); - myAuthPopulator.setSearchSubtree(true); - myAuthPopulator.setIgnorePartialResultException(true); - - auth.ldapAuthentication() - .userDnPatterns(ldap_user_dn_pattern) - .ldapAuthoritiesPopulator(myAuthPopulator) - .contextSource(contextSource); - } + /** External LDAP configuration properties */ + @Value("${ldap.enabled:false}") + boolean ldap_enabled; - if (embedded_ldap_enabled) { - DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(embedded_ldap_url); - contextSource.afterPropertiesSet(); + @Value("${ldap.urls:ldaps://localhost:389/}") + String ldap_url; - DefaultLdapAuthoritiesPopulator myAuthPopulator = new DefaultLdapAuthoritiesPopulator(contextSource, embedded_ldap_groups_search_base); - myAuthPopulator.setGroupSearchFilter(embedded_ldap_groups_search_pattern); - myAuthPopulator.setSearchSubtree(true); - myAuthPopulator.setIgnorePartialResultException(true); + @Value("${ldap.user.dn.pattern}") + String ldap_user_dn_pattern; + @Value("${ldap.groups.search.base}") + String ldap_groups_search_base; - auth.ldapAuthentication() - .userDnPatterns(embedded_ldap_user_dn_pattern) - .ldapAuthoritiesPopulator(myAuthPopulator) - .groupSearchBase("ou=Group") - .contextSource(contextSource); + @Value("${ldap.groups.search.pattern}") + String ldap_groups_search_pattern; - } + /** Embedded LDAP configuration properties */ + @Value("${embedded_ldap.enabled:false}") + boolean embedded_ldap_enabled; - if (demo_auth_enabled) { - // read from configuration, no default content - // interpret users, pwds, roles - // user may have multiple roles - - if (demo_auth_users != null - && demo_auth_pwds != null - && demo_auth_roles != null - && demo_auth_users.length > 0 - && demo_auth_users.length == demo_auth_pwds.length - && demo_auth_pwds.length == demo_auth_roles.length) { - - for (int i=0; i 0) { - auth.inMemoryAuthentication() - .withUser(demo_auth_users[i]) - .password(encoder().encode(demo_auth_pwds[i])) - .roles(userroles); - } - } - } - } + @Value("${embedded_ldap.urls:ldaps://localhost:389/}") + String embedded_ldap_url; + + @Value("${embedded_ldap.user.dn.pattern}") + String embedded_ldap_user_dn_pattern; + + @Value("${embedded_ldap.groups.search.base}") + String embedded_ldap_groups_search_base; + + @Value("${embedded_ldap.groups.search.pattern}") + String embedded_ldap_groups_search_pattern; + + /** Demo authorization based on in memory user credentials */ + @Value("${demo_auth.enabled:false}") + boolean demo_auth_enabled; + + @Value("${demo_auth.delimiter.roles::}") + String demo_auth_delimiter_roles; + + @Value("${demo_auth.users}") + String[] demo_auth_users; + + @Value("${demo_auth.pwds}") + String[] demo_auth_pwds; + + @Value("${demo_auth.roles}") + String[] demo_auth_roles; + + /** File based authentication */ + @Value("${file.auth.enabled:true}") + boolean file_enabled; + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + + if (ldap_enabled) { + DefaultSpringSecurityContextSource contextSource = + new DefaultSpringSecurityContextSource(ldap_url); + contextSource.afterPropertiesSet(); + + DefaultLdapAuthoritiesPopulator myAuthPopulator = + new DefaultLdapAuthoritiesPopulator(contextSource, ldap_groups_search_base); + myAuthPopulator.setGroupSearchFilter(ldap_groups_search_pattern); + myAuthPopulator.setSearchSubtree(true); + myAuthPopulator.setIgnorePartialResultException(true); + + auth.ldapAuthentication() + .userDnPatterns(ldap_user_dn_pattern) + .ldapAuthoritiesPopulator(myAuthPopulator) + .contextSource(contextSource); } - @Bean - public PasswordEncoder encoder() { - return new BCryptPasswordEncoder(); + if (embedded_ldap_enabled) { + DefaultSpringSecurityContextSource contextSource = + new DefaultSpringSecurityContextSource(embedded_ldap_url); + contextSource.afterPropertiesSet(); + + DefaultLdapAuthoritiesPopulator myAuthPopulator = + new DefaultLdapAuthoritiesPopulator(contextSource, embedded_ldap_groups_search_base); + myAuthPopulator.setGroupSearchFilter(embedded_ldap_groups_search_pattern); + myAuthPopulator.setSearchSubtree(true); + myAuthPopulator.setIgnorePartialResultException(true); + + auth.ldapAuthentication() + .userDnPatterns(embedded_ldap_user_dn_pattern) + .ldapAuthoritiesPopulator(myAuthPopulator) + .groupSearchBase("ou=Group") + .contextSource(contextSource); + } + + if (demo_auth_enabled) { + // read from configuration, no default content + // interpret users, pwds, roles + // user may have multiple roles + + if (demo_auth_users != null + && demo_auth_pwds != null + && demo_auth_roles != null + && demo_auth_users.length > 0 + && demo_auth_users.length == demo_auth_pwds.length + && demo_auth_pwds.length == demo_auth_roles.length) { + + for (int i = 0; i < demo_auth_users.length; i++) { + String[] userroles = demo_auth_roles[i].split(demo_auth_delimiter_roles); + if (userroles != null && userroles.length > 0) { + auth.inMemoryAuthentication() + .withUser(demo_auth_users[i]) + .password(encoder().encode(demo_auth_pwds[i])) + .roles(userroles); + } + } + } } + } -} \ No newline at end of file + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/entity/Channel.java b/src/main/java/org/phoebus/channelfinder/entity/Channel.java index 10d7f6a2..10f34779 100644 --- a/src/main/java/org/phoebus/channelfinder/entity/Channel.java +++ b/src/main/java/org/phoebus/channelfinder/entity/Channel.java @@ -1,13 +1,9 @@ package org.phoebus.channelfinder.entity; + /** - * #%L - * ChannelFinder Directory Service - * %% - * Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH - * %% - * Copyright (C) 2010 - 2012 Brookhaven National Laboratory - * All rights reserved. Use is subject to license terms. - * #L% + * #%L ChannelFinder Directory Service %% Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für + * Materialien und Energie GmbH %% Copyright (C) 2010 - 2012 Brookhaven National Laboratory All + * rights reserved. Use is subject to license terms. #L% */ import java.util.ArrayList; import java.util.List; @@ -18,229 +14,228 @@ * * @author Ralph Lange {@literal } */ - public class Channel { - private String name; - private String owner; - private List properties = new ArrayList<>(); - private List tags = new ArrayList<>(); - - /** Creates a new instance of Channel */ - public Channel() { - } - - /** - * Creates a new instance of Channel. - * - * @param name - channel name - */ - public Channel(String name) { - this.name = name; - } - - /** - * Creates a new instance of Channel. - * - * @param name - channel name - * @param owner - owner name - */ - public Channel(String name, String owner) { - this.name = name; - this.owner = owner; - } - - /** - * - * @param name - channel name - * @param owner - channel owner - * @param properties - list of channel properties - * @param tags - list of channel tags - */ - public Channel(String name, String owner, List properties, List tags) { - this.name = name; - this.owner = owner; - this.properties = properties; - this.tags = tags; - } - - /** - * Getter for channel name. - * - * @return name - channel name - */ - public String getName() { - return name; - } - - /** - * Setter for channel name. - * - * @param name - channel name - */ - public void setName(String name) { - this.name = name; - } - - /** - * Getter for channel owner. - * - * @return owner - channel owner - */ - public String getOwner() { - return owner; - } - - /** - * Setter for channel owner. - * - * @param owner - channel owner - */ - public void setOwner(String owner) { - this.owner = owner; - } - - public List getProperties() { - return properties; - } - - public void setProperties(List properties) { - this.properties = properties; - } - - public List getTags() { - return tags; - } - - public void setTags(List tags) { - this.tags = tags; - } - - /** - * Add the given tag to the list of tags associated with this channel - * If the tag already exists then it is replaced with tag - * @param tag the tag to be added to the channel - */ - public void addTag(Tag tag) { - // If the tag already exists, then filter it out - this.tags = this.tags.stream().filter(t -> - !t.getName().equals(tag.getName()) - ).collect(Collectors.toList()); - // add the updated version of the tag - this.tags.add(tag); - } - - /** - * Remove the given tag to the list of tags associated with this channel - * @param tag the tag to be removed from channel - */ - public void removeTag(Tag tag) { - this.tags = this.tags.stream().filter(t -> - !t.getName().equals(tag.getName()) - ).collect(Collectors.toList()); - } - - /** - * Add the given list of tags to the list of tags associated with this channel - * @param tags the tags to be added to the channel - */ - public void addTags(List tags) { - tags.forEach(this::addTag); - } - - /** - * Add the given property to the list of properties associated with this channel - * If the property already exists then it is replaced with the provided one - * @param property the property to be added to the channel - */ - public void addProperty(Property property) { - // If the property already exists, then filter it out - this.properties = this.properties.stream().filter(p -> - !p.getName().equals(property.getName()) - ).collect(Collectors.toList()); - // add the updated version of the property - this.properties.add(property); - } - - /** - * Remove the given property to the list of properties associated with this channel - * @param property the property to be removed from the channel - */ - public void removeProperty(Property property) { - this.properties = this.properties.stream().filter(p -> - !p.getName().equals(property.getName()) - ).collect(Collectors.toList()); - } - - /** - * Add the given list of properties to the properties associated with this channel - * @param properties the properties to be added to the channel - */ - public void addProperties(List properties) { - properties.forEach(this::addProperty); - } - /** - * Creates a compact string representation for the log. - * - * @return string representation - */ - public String toLog() { - return this.getName() + "(" + this.getOwner() + "):[" - + (this.properties) - + (this.tags) - + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((owner == null) ? 0 : owner.hashCode()); - result = prime * result + ((properties == null) ? 0 : properties.hashCode()); - result = prime * result + ((tags == null) ? 0 : tags.hashCode()); - return result; - } - - @Override - public String toString() { - return "Channel{" + - "name='" + name + '\'' + - ", owner='" + owner + '\'' + - ", properties=" + properties + - ", tags=" + tags + - '}'; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Channel other = (Channel) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (owner == null) { - if (other.owner != null) - return false; - } else if (!owner.equals(other.owner)) - return false; - if (properties == null) { - if (other.properties != null) - return false; - } else if (!properties.equals(other.properties)) - return false; - if (tags == null) { - if (other.tags != null) - return false; - } else if (!tags.equals(other.tags)) - return false; - return true; - } - + private String name; + private String owner; + private List properties = new ArrayList<>(); + private List tags = new ArrayList<>(); + + /** Creates a new instance of Channel */ + public Channel() {} + + /** + * Creates a new instance of Channel. + * + * @param name - channel name + */ + public Channel(String name) { + this.name = name; + } + + /** + * Creates a new instance of Channel. + * + * @param name - channel name + * @param owner - owner name + */ + public Channel(String name, String owner) { + this.name = name; + this.owner = owner; + } + + /** + * @param name - channel name + * @param owner - channel owner + * @param properties - list of channel properties + * @param tags - list of channel tags + */ + public Channel(String name, String owner, List properties, List tags) { + this.name = name; + this.owner = owner; + this.properties = properties; + this.tags = tags; + } + + /** + * Getter for channel name. + * + * @return name - channel name + */ + public String getName() { + return name; + } + + /** + * Setter for channel name. + * + * @param name - channel name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Getter for channel owner. + * + * @return owner - channel owner + */ + public String getOwner() { + return owner; + } + + /** + * Setter for channel owner. + * + * @param owner - channel owner + */ + public void setOwner(String owner) { + this.owner = owner; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + /** + * Add the given tag to the list of tags associated with this channel If the tag already exists + * then it is replaced with tag + * + * @param tag the tag to be added to the channel + */ + public void addTag(Tag tag) { + // If the tag already exists, then filter it out + this.tags = + this.tags.stream() + .filter(t -> !t.getName().equals(tag.getName())) + .collect(Collectors.toList()); + // add the updated version of the tag + this.tags.add(tag); + } + + /** + * Remove the given tag to the list of tags associated with this channel + * + * @param tag the tag to be removed from channel + */ + public void removeTag(Tag tag) { + this.tags = + this.tags.stream() + .filter(t -> !t.getName().equals(tag.getName())) + .collect(Collectors.toList()); + } + + /** + * Add the given list of tags to the list of tags associated with this channel + * + * @param tags the tags to be added to the channel + */ + public void addTags(List tags) { + tags.forEach(this::addTag); + } + + /** + * Add the given property to the list of properties associated with this channel If the property + * already exists then it is replaced with the provided one + * + * @param property the property to be added to the channel + */ + public void addProperty(Property property) { + // If the property already exists, then filter it out + this.properties = + this.properties.stream() + .filter(p -> !p.getName().equals(property.getName())) + .collect(Collectors.toList()); + // add the updated version of the property + this.properties.add(property); + } + + /** + * Remove the given property to the list of properties associated with this channel + * + * @param property the property to be removed from the channel + */ + public void removeProperty(Property property) { + this.properties = + this.properties.stream() + .filter(p -> !p.getName().equals(property.getName())) + .collect(Collectors.toList()); + } + + /** + * Add the given list of properties to the properties associated with this channel + * + * @param properties the properties to be added to the channel + */ + public void addProperties(List properties) { + properties.forEach(this::addProperty); + } + + /** + * Creates a compact string representation for the log. + * + * @return string representation + */ + public String toLog() { + return this.getName() + "(" + this.getOwner() + "):[" + (this.properties) + (this.tags) + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((owner == null) ? 0 : owner.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.hashCode()); + return result; + } + + @Override + public String toString() { + return "Channel{" + + "name='" + + name + + '\'' + + ", owner='" + + owner + + '\'' + + ", properties=" + + properties + + ", tags=" + + tags + + '}'; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Channel other = (Channel) obj; + if (name == null) { + if (other.name != null) return false; + } else if (!name.equals(other.name)) return false; + if (owner == null) { + if (other.owner != null) return false; + } else if (!owner.equals(other.owner)) return false; + if (properties == null) { + if (other.properties != null) return false; + } else if (!properties.equals(other.properties)) return false; + if (tags == null) { + if (other.tags != null) return false; + } else if (!tags.equals(other.tags)) return false; + return true; + } } diff --git a/src/main/java/org/phoebus/channelfinder/entity/Property.java b/src/main/java/org/phoebus/channelfinder/entity/Property.java index 3be7ccaf..a9e21fd2 100644 --- a/src/main/java/org/phoebus/channelfinder/entity/Property.java +++ b/src/main/java/org/phoebus/channelfinder/entity/Property.java @@ -1,17 +1,11 @@ package org.phoebus.channelfinder.entity; + /** - * #%L - * ChannelFinder Directory Service - * %% - * Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH - * %% - * Copyright (C) 2010 - 2012 Brookhaven National Laboratory - * All rights reserved. Use is subject to license terms. - * #L% + * #%L ChannelFinder Directory Service %% Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für + * Materialien und Energie GmbH %% Copyright (C) 2010 - 2012 Brookhaven National Laboratory All + * rights reserved. Use is subject to license terms. #L% */ - import com.fasterxml.jackson.annotation.JsonIgnore; - import java.util.ArrayList; import java.util.List; @@ -21,201 +15,190 @@ * @author Ralph Lange {@literal } */ public class Property { - private String name; - private String owner; - - @Override - public String toString() { - return "Property{" + - "name='" + name + '\'' + - ", owner='" + owner + '\'' + - ", value='" + value + '\'' + - ", channels=" + channels + - '}'; - } - - private String value; - private List channels = new ArrayList<>(); - - /** - * Creates a new instance of Property. - * - */ - public Property() { - } - - /** - * Creates a new instance of Property. - * - * @param name property name - * @param owner property owner - */ - public Property(String name, String owner) { - this.owner = owner; - this.name = name; - } - - /** - * Creates a new instance of Property. - * - * @param name property name - * @param owner property owner - * @param value property value - */ - public Property(String name, String owner, String value) { - this.value = value; - this.owner = owner; - this.name = name; - } - - /** - * Getter for property name. - * - * @return property name - */ - public String getName() { - return name; - } - - /** - * Setter for property name. - * - * @param name property name - */ - public void setName(String name) { - this.name = name; - } - - /** - * Getter for property value. - * - * @return property value - */ - public String getValue() { - return value; - } - - /** - * Setter for property value. - * - * @param value property value - */ - public void setValue(String value) { - this.value = value; - } - - /** - * Getter for property owner. - * - * @return property owner - */ - public String getOwner() { - return owner; - } - - /** - * Setter for property owner. - * - * @param owner property owner - */ - public void setOwner(String owner) { - this.owner = owner; - } - - /** - * Get the list of channels associated with this property - * @return {@link List} of channels - */ - public List getChannels() { - return channels; - } - - /** - * set the channels associated with this property - * - * @param channels - list of channels - */ - public void setChannels(List channels) { - this.channels = channels; - } - - /** - * Creates a compact string representation for the log. - * - * @return string representation for log - */ - public String toLog() { - if (this.channels == null) { - return this.getName() + "(" + this.getOwner() + ")"; - } else { - return this.getName() + "(" + this.getOwner() + ")" - + (this.channels); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((channels == null) ? 0 : channels.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((owner == null) ? 0 : owner.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Property other = (Property) obj; - if (channels == null) { - if (other.channels != null) - return false; - } else if (!channels.equals(other.channels)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (owner == null) { - if (other.owner != null) - return false; - } else if (!owner.equals(other.owner)) - return false; - if (value == null) { - return other.value == null; - } else return value.equals(other.value); - } - - /** - * A filter to be used with the jackson mapper to ignore the embedded - * xmlchannels in the property object - * - * @author Kunal Shroff - * - */ - public abstract static class OnlyProperty { - @JsonIgnore - private List channels; - } - - /** - * A filter to be used with the jackson mapper to ignore the embedded - * xmlchannels and value in the property object - * - * @author Kunal Shroff - * - */ - public abstract static class OnlyNameOwnerProperty { - @JsonIgnore - private String value; - @JsonIgnore - private List channels; - } + private String name; + private String owner; + + @Override + public String toString() { + return "Property{" + + "name='" + + name + + '\'' + + ", owner='" + + owner + + '\'' + + ", value='" + + value + + '\'' + + ", channels=" + + channels + + '}'; + } + + private String value; + private List channels = new ArrayList<>(); + + /** Creates a new instance of Property. */ + public Property() {} + + /** + * Creates a new instance of Property. + * + * @param name property name + * @param owner property owner + */ + public Property(String name, String owner) { + this.owner = owner; + this.name = name; + } + + /** + * Creates a new instance of Property. + * + * @param name property name + * @param owner property owner + * @param value property value + */ + public Property(String name, String owner, String value) { + this.value = value; + this.owner = owner; + this.name = name; + } + + /** + * Getter for property name. + * + * @return property name + */ + public String getName() { + return name; + } + + /** + * Setter for property name. + * + * @param name property name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Getter for property value. + * + * @return property value + */ + public String getValue() { + return value; + } + + /** + * Setter for property value. + * + * @param value property value + */ + public void setValue(String value) { + this.value = value; + } + + /** + * Getter for property owner. + * + * @return property owner + */ + public String getOwner() { + return owner; + } + + /** + * Setter for property owner. + * + * @param owner property owner + */ + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * Get the list of channels associated with this property + * + * @return {@link List} of channels + */ + public List getChannels() { + return channels; + } + + /** + * set the channels associated with this property + * + * @param channels - list of channels + */ + public void setChannels(List channels) { + this.channels = channels; + } + + /** + * Creates a compact string representation for the log. + * + * @return string representation for log + */ + public String toLog() { + if (this.channels == null) { + return this.getName() + "(" + this.getOwner() + ")"; + } else { + return this.getName() + "(" + this.getOwner() + ")" + (this.channels); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((channels == null) ? 0 : channels.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((owner == null) ? 0 : owner.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Property other = (Property) obj; + if (channels == null) { + if (other.channels != null) return false; + } else if (!channels.equals(other.channels)) return false; + if (name == null) { + if (other.name != null) return false; + } else if (!name.equals(other.name)) return false; + if (owner == null) { + if (other.owner != null) return false; + } else if (!owner.equals(other.owner)) return false; + if (value == null) { + return other.value == null; + } else return value.equals(other.value); + } + + /** + * A filter to be used with the jackson mapper to ignore the embedded xmlchannels in the property + * object + * + * @author Kunal Shroff + */ + public abstract static class OnlyProperty { + @JsonIgnore private List channels; + } + + /** + * A filter to be used with the jackson mapper to ignore the embedded xmlchannels and value in the + * property object + * + * @author Kunal Shroff + */ + public abstract static class OnlyNameOwnerProperty { + @JsonIgnore private String value; + @JsonIgnore private List channels; + } } diff --git a/src/main/java/org/phoebus/channelfinder/entity/Scroll.java b/src/main/java/org/phoebus/channelfinder/entity/Scroll.java index 51be0ae9..30c71d92 100644 --- a/src/main/java/org/phoebus/channelfinder/entity/Scroll.java +++ b/src/main/java/org/phoebus/channelfinder/entity/Scroll.java @@ -4,49 +4,42 @@ import java.util.List; public class Scroll { - private String id; - private List channels = new ArrayList<>(); - - @Override - public String toString() { - return "Scroll{" + - "id='" + id + '\'' + - ", channels=" + channels + - '}'; - } - - /** - * Creates a new instance of Scroll. - * - */ - public Scroll() { - } - - /** - * Creates a new instance of Scroll. - * - * @param id - scroll name - * @param channels - list of channels - */ - public Scroll(String id, List channels) { - super(); - this.id = id; - this.channels = channels; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public List getChannels() { - return channels; - } - - public void setChannels(List channels) { - this.channels = channels; - } -} \ No newline at end of file + private String id; + private List channels = new ArrayList<>(); + + @Override + public String toString() { + return "Scroll{" + "id='" + id + '\'' + ", channels=" + channels + '}'; + } + + /** Creates a new instance of Scroll. */ + public Scroll() {} + + /** + * Creates a new instance of Scroll. + * + * @param id - scroll name + * @param channels - list of channels + */ + public Scroll(String id, List channels) { + super(); + this.id = id; + this.channels = channels; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getChannels() { + return channels; + } + + public void setChannels(List channels) { + this.channels = channels; + } +} diff --git a/src/main/java/org/phoebus/channelfinder/entity/SearchResult.java b/src/main/java/org/phoebus/channelfinder/entity/SearchResult.java index 43ab51d3..02239d3c 100644 --- a/src/main/java/org/phoebus/channelfinder/entity/SearchResult.java +++ b/src/main/java/org/phoebus/channelfinder/entity/SearchResult.java @@ -1,31 +1,25 @@ package org.phoebus.channelfinder.entity; import com.google.common.base.Objects; - import java.util.List; public record SearchResult(List channels, long count) { - @Override - public String toString() { - return "SearchResult{" + - "count=" + count + - ", channels=" + channels + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SearchResult that = (SearchResult) o; - return count == that.count && Objects.equal(channels, that.channels); - } - - @Override - public int hashCode() { - return Objects.hashCode(count, channels); - } - - -} \ No newline at end of file + @Override + public String toString() { + return "SearchResult{" + "count=" + count + ", channels=" + channels + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SearchResult that = (SearchResult) o; + return count == that.count && Objects.equal(channels, that.channels); + } + + @Override + public int hashCode() { + return Objects.hashCode(count, channels); + } +} diff --git a/src/main/java/org/phoebus/channelfinder/entity/Tag.java b/src/main/java/org/phoebus/channelfinder/entity/Tag.java index ed2166b7..f1baed73 100644 --- a/src/main/java/org/phoebus/channelfinder/entity/Tag.java +++ b/src/main/java/org/phoebus/channelfinder/entity/Tag.java @@ -1,17 +1,11 @@ package org.phoebus.channelfinder.entity; + /** - * #%L - * ChannelFinder Directory Service - * %% - * Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH - * %% - * Copyright (C) 2010 - 2012 Brookhaven National Laboratory - * All rights reserved. Use is subject to license terms. - * #L% + * #%L ChannelFinder Directory Service %% Copyright (C) 2010 - 2012 Helmholtz-Zentrum Berlin für + * Materialien und Energie GmbH %% Copyright (C) 2010 - 2012 Brookhaven National Laboratory All + * rights reserved. Use is subject to license terms. #L% */ - import com.fasterxml.jackson.annotation.JsonIgnore; - import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -22,159 +16,155 @@ * @author Ralph Lange {@literal } */ public class Tag { - private String name; - private String owner; - - @Override - public String toString() { - return "Tag{" + - "name='" + name + '\'' + - ", owner='" + owner + '\'' + - ", channels=" + channels + - '}'; - } - - private List channels = new ArrayList<>(); - - /** - * Creates a new instance of Tag. - * - */ - public Tag() { - } - - /** - * Creates a new instance of Tag. - * - * @param name name of new tag - */ - public Tag(String name) { - this.name = name; - } - - /** - * Creates a new instance of Tag. - * - * @param name name of new tag - * @param owner owner of new tag - */ - public Tag(String name, String owner) { - this.name = name; - this.owner = owner; - } - - /** - * Getter for tag name. - * - * @return tag name - */ - public String getName() { - return name; - } - - /** - * Setter for tag name. - * - * @param name tag name - */ - public void setName(String name) { - this.name = name; - } - - /** - * Getter for tag owner. - * - * @return tag owner - */ - public String getOwner() { - return owner; + private String name; + private String owner; + + @Override + public String toString() { + return "Tag{" + + "name='" + + name + + '\'' + + ", owner='" + + owner + + '\'' + + ", channels=" + + channels + + '}'; + } + + private List channels = new ArrayList<>(); + + /** Creates a new instance of Tag. */ + public Tag() {} + + /** + * Creates a new instance of Tag. + * + * @param name name of new tag + */ + public Tag(String name) { + this.name = name; + } + + /** + * Creates a new instance of Tag. + * + * @param name name of new tag + * @param owner owner of new tag + */ + public Tag(String name, String owner) { + this.name = name; + this.owner = owner; + } + + /** + * Getter for tag name. + * + * @return tag name + */ + public String getName() { + return name; + } + + /** + * Setter for tag name. + * + * @param name tag name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Getter for tag owner. + * + * @return tag owner + */ + public String getOwner() { + return owner; + } + + /** + * Setter for tag owner. + * + * @param owner tag owner + */ + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * Getter for tag's XmlChannels. + * + * @return XmlChannels object + */ + public List getChannels() { + return channels; + } + + /** + * Setter for tag's XmlChannels. + * + * @param channels XmlChannels object + */ + public void setChannels(List channels) { + this.channels = channels; + } + + /** + * Creates a compact string representation for the log. + * + * @return string representation for log + */ + public String toLog() { + if (this.channels == null) { + return this.getName() + "(" + this.getOwner() + ")"; + } else { + return this.getName() + + "(" + + this.getOwner() + + ")" + + " [ " + + (this.channels.stream().map(Channel::toLog).collect(Collectors.joining(","))) + + " ] "; } - - /** - * Setter for tag owner. - * - * @param owner tag owner - */ - public void setOwner(String owner) { - this.owner = owner; - } - - /** - * Getter for tag's XmlChannels. - * - * @return XmlChannels object - */ - public List getChannels() { - return channels; - } - - /** - * Setter for tag's XmlChannels. - * - * @param channels XmlChannels object - */ - public void setChannels(List channels) { - this.channels = channels; - } - - /** - * Creates a compact string representation for the log. - * - * @return string representation for log - */ - public String toLog() { - if (this.channels == null) { - return this.getName() + "(" + this.getOwner() + ")"; - } else { - return this.getName() + "(" + this.getOwner() + ")" + " [ " - + (this.channels.stream().map(Channel::toLog).collect(Collectors.joining(","))) + " ] "; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((channels == null) ? 0 : channels.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((owner == null) ? 0 : owner.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Tag other = (Tag) obj; - if (channels == null) { - if (other.channels != null) - return false; - } else if (!channels.equals(other.channels)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (owner == null) { - return other.owner == null; - } else return owner.equals(other.owner); - } - - /** - * A filter to be used with the jackson mapper to ignore the embedded - * xmlchannels in the tag object - * - * @author Kunal Shroff - * - */ - public abstract static class OnlyTag { - @JsonIgnore - private List channels; - } - + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((channels == null) ? 0 : channels.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((owner == null) ? 0 : owner.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Tag other = (Tag) obj; + if (channels == null) { + if (other.channels != null) return false; + } else if (!channels.equals(other.channels)) return false; + if (name == null) { + if (other.name != null) return false; + } else if (!name.equals(other.name)) return false; + if (owner == null) { + return other.owner == null; + } else return owner.equals(other.owner); + } + + /** + * A filter to be used with the jackson mapper to ignore the embedded xmlchannels in the tag + * object + * + * @author Kunal Shroff + */ + public abstract static class OnlyTag { + @JsonIgnore private List channels; + } } diff --git a/src/main/java/org/phoebus/channelfinder/epics/ChannelFinderEpicsService.java b/src/main/java/org/phoebus/channelfinder/epics/ChannelFinderEpicsService.java index c26e2e68..96c00786 100644 --- a/src/main/java/org/phoebus/channelfinder/epics/ChannelFinderEpicsService.java +++ b/src/main/java/org/phoebus/channelfinder/epics/ChannelFinderEpicsService.java @@ -7,10 +7,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; - import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; - import org.epics.pva.data.PVABoolArray; import org.epics.pva.data.PVAStringArray; import org.epics.pva.data.PVAStructure; @@ -18,180 +16,189 @@ import org.epics.pva.data.nt.NotValueException; import org.epics.pva.data.nt.PVATable; import org.epics.pva.data.nt.PVAURI; +import org.epics.pva.server.PVAServer; import org.epics.pva.server.RPCService; -import org.phoebus.channelfinder.entity.Channel; +import org.epics.pva.server.ServerPV; import org.phoebus.channelfinder.ChannelRepository; +import org.phoebus.channelfinder.entity.Channel; 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; -import org.epics.pva.server.PVAServer; -import org.epics.pva.server.ServerPV; /** * A pva RPC service for channelfinder - *

- * Request: - *

- * The client requests a query as a NTURI pvStructure. - *

- * Result: - *

- * The service returns the result as an NTTable pvStructure. - * - * @author Kunal Shroff * + *

Request: + * + *

The client requests a query as a NTURI pvStructure. + * + *

Result: + * + *

The service returns the result as an NTTable pvStructure. + * + * @author Kunal Shroff */ @Service -@ComponentScan(basePackages="org.phoebus.channelfinder") +@ComponentScan(basePackages = "org.phoebus.channelfinder") public class ChannelFinderEpicsService { - private static final Logger logger = Logger.getLogger(ChannelFinderEpicsService.class.getName()); + private static final Logger logger = Logger.getLogger(ChannelFinderEpicsService.class.getName()); - public static final String SERVICE_DESC = "cfService:query"; + public static final String SERVICE_DESC = "cfService:query"; - public static final String COLUMN_CHANNEL_NAME = "channelName"; - public static final String COLUMN_OWNER = "owner"; + public static final String COLUMN_CHANNEL_NAME = "channelName"; + public static final String COLUMN_OWNER = "owner"; - @Autowired - ChannelRepository repository; + @Autowired ChannelRepository repository; - PVAServer server; - ServerPV serverPV; + PVAServer server; + ServerPV serverPV; - @PostConstruct - public void init() throws Exception { + @PostConstruct + public void init() throws Exception { - logger.log(Level.INFO, "Launching the epics rpc channelfinder service: " + SERVICE_DESC); + logger.log(Level.INFO, "Launching the epics rpc channelfinder service: " + SERVICE_DESC); - server = new PVAServer(); + server = new PVAServer(); - logger.log(Level.INFO, SERVICE_DESC + " initializing..."); - ChannelFinderServiceImpl service = new ChannelFinderServiceImpl(repository); - serverPV = server.createPV(SERVICE_DESC, service); - logger.log(Level.INFO, SERVICE_DESC + " is operational."); + logger.log(Level.INFO, SERVICE_DESC + " initializing..."); + ChannelFinderServiceImpl service = new ChannelFinderServiceImpl(repository); + serverPV = server.createPV(SERVICE_DESC, service); + logger.log(Level.INFO, SERVICE_DESC + " is operational."); + } - - } + @PreDestroy + public void onDestroy() { + logger.log(Level.INFO, "Shutting down service " + SERVICE_DESC); + logger.info("Shutting down service " + SERVICE_DESC); + serverPV.close(); + server.close(); + logger.info(SERVICE_DESC + " Shutdown complete."); + } - @PreDestroy - public void onDestroy() { - logger.log(Level.INFO, "Shutting down service " + SERVICE_DESC); - logger.info("Shutting down service " + SERVICE_DESC); - serverPV.close(); - server.close(); - logger.info(SERVICE_DESC + " Shutdown complete."); - } + private static class ChannelFinderServiceImpl implements RPCService { - private static class ChannelFinderServiceImpl implements RPCService { + private final ChannelRepository repository; + public ChannelFinderServiceImpl(ChannelRepository repository) { + this.repository = repository; + logger.log(Level.INFO, "start"); + } - private final ChannelRepository repository; + @Override + public PVAStructure call(PVAStructure args) throws Exception { + logger.log(Level.FINE, args::toString); + HandlerQuery query = new HandlerQuery(args, repository); + return query.run(); + } - public ChannelFinderServiceImpl(ChannelRepository repository) { - this.repository = repository; - logger.log(Level.INFO, "start"); - } + private static class HandlerQuery { - @Override - public PVAStructure call(PVAStructure args) throws Exception { - logger.log(Level.FINE, args::toString); - HandlerQuery query = new HandlerQuery(args, repository); - return query.run(); - } + private final PVAStructure args; + private final ChannelRepository channelRepository; - private static class HandlerQuery { + public HandlerQuery(PVAStructure args, ChannelRepository channelRepository) { + this.args = args; + this.channelRepository = channelRepository; + } - private final PVAStructure args; - private final ChannelRepository channelRepository; + public PVAStructure run() throws MustBeArrayException { - public HandlerQuery(PVAStructure args, ChannelRepository channelRepository) { - this.args = args; - this.channelRepository = channelRepository; + MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + PVAURI uri = PVAURI.fromStructure(args); + Map query; + try { + query = uri.getQuery(); + } catch (NotValueException e) { + logger.log(Level.WARNING, () -> "Query " + uri + " not valid." + e.getMessage()); + throw new UnsupportedOperationException("The requested operation is not supported."); + } + for (String parameter : query.keySet()) { + String value = query.get(parameter); + if (value != null && !value.isEmpty()) { + switch (parameter) { + case "_name": + searchParameters.put("~name", List.of(value)); + break; + case "_tag": + searchParameters.put("~tag", List.of(value)); + break; + case "_size": + searchParameters.put("~size", List.of(value)); + break; + case "_from": + searchParameters.put("~from", List.of(value)); + break; + default: + searchParameters.put(parameter, List.of(value)); + break; } + } + } - public PVAStructure run() throws MustBeArrayException { - - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - PVAURI uri = PVAURI.fromStructure(args); - Map query; - try { - query = uri.getQuery(); - } catch (NotValueException e) { - logger.log(Level.WARNING, () -> "Query " + uri + " not valid." + e.getMessage()); - throw new UnsupportedOperationException("The requested operation is not supported."); - } - for (String parameter : query.keySet()) { - String value = query.get(parameter); - if (value != null && !value.isEmpty()) { - switch (parameter) { - case "_name": - searchParameters.put("~name", List.of(value)); - break; - case "_tag": - searchParameters.put("~tag", List.of(value)); - break; - case "_size": - searchParameters.put("~size", List.of(value)); - break; - case "_from": - searchParameters.put("~from", List.of(value)); - break; - default: - searchParameters.put(parameter, List.of(value)); - break; - } - } - } - - List result = channelRepository.search(searchParameters).channels(); - - final Map> channelTable = new HashMap<>(); - final Map> channelPropertyTable = new HashMap<>(); - final Map channelTagTable = new HashMap<>(); - channelTable.put(COLUMN_CHANNEL_NAME, Arrays.asList(new String[result.size()])); - channelTable.put(COLUMN_OWNER, Arrays.asList(new String[result.size()])); + List result = channelRepository.search(searchParameters).channels(); - AtomicInteger counter = new AtomicInteger(0); + final Map> channelTable = new HashMap<>(); + final Map> channelPropertyTable = new HashMap<>(); + final Map channelTagTable = new HashMap<>(); + channelTable.put(COLUMN_CHANNEL_NAME, Arrays.asList(new String[result.size()])); + channelTable.put(COLUMN_OWNER, Arrays.asList(new String[result.size()])); - result.forEach(ch -> { + AtomicInteger counter = new AtomicInteger(0); - int index = counter.getAndIncrement(); + result.forEach( + ch -> { + int index = counter.getAndIncrement(); - channelTable.get(COLUMN_CHANNEL_NAME).set(index, ch.getName()); - channelTable.get(COLUMN_OWNER).set(index, ch.getOwner()); + channelTable.get(COLUMN_CHANNEL_NAME).set(index, ch.getName()); + channelTable.get(COLUMN_OWNER).set(index, ch.getOwner()); - ch.getTags().forEach(t -> { + ch.getTags() + .forEach( + t -> { if (!channelTagTable.containsKey(t.getName())) { - channelTagTable.put(t.getName(), new boolean[result.size()]); + channelTagTable.put(t.getName(), new boolean[result.size()]); } channelTagTable.get(t.getName())[index] = true; - }); + }); - ch.getProperties().forEach(prop -> { + ch.getProperties() + .forEach( + prop -> { if (!channelPropertyTable.containsKey(prop.getName())) { - channelPropertyTable.put(prop.getName(), Arrays.asList(new String[result.size()])); + channelPropertyTable.put( + prop.getName(), Arrays.asList(new String[result.size()])); } channelPropertyTable.get(prop.getName()).set(index, prop.getValue()); - }); - }); - PVATable.PVATableBuilder ntTableBuilder = PVATable.PVATableBuilder.aPVATable().name(SERVICE_DESC); - - channelTable.keySet().forEach(name -> - ntTableBuilder.addColumn(new PVAStringArray(name, channelTable.get(name).toArray(String[]::new))) - ); - channelPropertyTable.keySet().forEach(name -> - ntTableBuilder.addColumn(new PVAStringArray(name, channelPropertyTable.get(name).toArray(String[]::new))) - ); - channelTagTable.keySet().forEach(name -> - ntTableBuilder.addColumn(new PVABoolArray(name, channelTagTable.get(name))) - ); - - logger.log(Level.FINE, ntTableBuilder::toString); - return ntTableBuilder.build(); - } - } - + }); + }); + PVATable.PVATableBuilder ntTableBuilder = + PVATable.PVATableBuilder.aPVATable().name(SERVICE_DESC); + + channelTable + .keySet() + .forEach( + name -> + ntTableBuilder.addColumn( + new PVAStringArray(name, channelTable.get(name).toArray(String[]::new)))); + channelPropertyTable + .keySet() + .forEach( + name -> + ntTableBuilder.addColumn( + new PVAStringArray( + name, channelPropertyTable.get(name).toArray(String[]::new)))); + channelTagTable + .keySet() + .forEach( + name -> + ntTableBuilder.addColumn(new PVABoolArray(name, channelTagTable.get(name)))); + + logger.log(Level.FINE, ntTableBuilder::toString); + return ntTableBuilder.build(); + } } + } } diff --git a/src/main/java/org/phoebus/channelfinder/epics/NTXmlUtil.java b/src/main/java/org/phoebus/channelfinder/epics/NTXmlUtil.java index d0228687..60e1182d 100644 --- a/src/main/java/org/phoebus/channelfinder/epics/NTXmlUtil.java +++ b/src/main/java/org/phoebus/channelfinder/epics/NTXmlUtil.java @@ -1,5 +1,13 @@ package org.phoebus.channelfinder.epics; +import static org.phoebus.channelfinder.epics.ChannelFinderEpicsService.COLUMN_CHANNEL_NAME; +import static org.phoebus.channelfinder.epics.ChannelFinderEpicsService.COLUMN_OWNER; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import org.epics.pva.data.PVABoolArray; import org.epics.pva.data.PVAData; import org.epics.pva.data.PVAStringArray; @@ -9,65 +17,55 @@ import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.entity.Tag; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static org.phoebus.channelfinder.epics.ChannelFinderEpicsService.COLUMN_CHANNEL_NAME; -import static org.phoebus.channelfinder.epics.ChannelFinderEpicsService.COLUMN_OWNER; - public class NTXmlUtil { - /** - * A helper method to convert the result of the channelfinder v4 service - * to a list of {@link Channel} - * - * @param result - NTTable returned by the channelfinder service - * @return list of channels - */ - public static synchronized List parse(PVAStructure result) { - PVATable table = PVATable.fromStructure(result); + /** + * A helper method to convert the result of the channelfinder v4 service to a list of {@link + * Channel} + * + * @param result - NTTable returned by the channelfinder service + * @return list of channels + */ + public static synchronized List parse(PVAStructure result) { + PVATable table = PVATable.fromStructure(result); - List names = Arrays.asList(table.getLabels().get()); - List channels = new ArrayList<>(); + List names = Arrays.asList(table.getLabels().get()); + List channels = new ArrayList<>(); - if (names.contains(COLUMN_CHANNEL_NAME)) { - PVAStringArray array = table.getColumn(COLUMN_CHANNEL_NAME); - Arrays.stream(array.get()).forEach(c -> channels.add(new Channel(c))); - } + if (names.contains(COLUMN_CHANNEL_NAME)) { + PVAStringArray array = table.getColumn(COLUMN_CHANNEL_NAME); + Arrays.stream(array.get()).forEach(c -> channels.add(new Channel(c))); + } - if (names.contains(COLUMN_OWNER)) { - PVAStringArray array = table.getColumn(COLUMN_OWNER); - List> owners = - Arrays.stream(array.get()).map(Optional::ofNullable).collect(Collectors.toList()); - for (int i = 0; i < channels.size(); i++) { - if (owners.get(i).isPresent()) - channels.get(i).setOwner(owners.get(i).get()); - } - } + if (names.contains(COLUMN_OWNER)) { + PVAStringArray array = table.getColumn(COLUMN_OWNER); + List> owners = + Arrays.stream(array.get()).map(Optional::ofNullable).collect(Collectors.toList()); + for (int i = 0; i < channels.size(); i++) { + if (owners.get(i).isPresent()) channels.get(i).setOwner(owners.get(i).get()); + } + } - for (String name : names) { - if (!name.equals(COLUMN_CHANNEL_NAME) && !name.equals(COLUMN_OWNER)) { - PVAData pvaData = table.getColumn(name); + for (String name : names) { + if (!name.equals(COLUMN_CHANNEL_NAME) && !name.equals(COLUMN_OWNER)) { + PVAData pvaData = table.getColumn(name); - if (pvaData.getClass().equals(PVABoolArray.class)) { - boolean[] array = ((PVABoolArray) pvaData).get(); - for (int i = 0; i < array.length; i++) { - if (array[i]) { - channels.get(i).getTags().add(new Tag(name)); - } - } - } else if (pvaData.getClass().equals(PVAStringArray.class)) { - String[] array = ((PVAStringArray) pvaData).get(); - for (int i = 0; i < array.length; i++) { - if (array[i] != null) { - channels.get(i).getProperties().add(new Property(name, null, array[i])); - } - } - } + if (pvaData.getClass().equals(PVABoolArray.class)) { + boolean[] array = ((PVABoolArray) pvaData).get(); + for (int i = 0; i < array.length; i++) { + if (array[i]) { + channels.get(i).getTags().add(new Tag(name)); + } + } + } else if (pvaData.getClass().equals(PVAStringArray.class)) { + String[] array = ((PVAStringArray) pvaData).get(); + for (int i = 0; i < array.length; i++) { + if (array[i] != null) { + channels.get(i).getProperties().add(new Property(name, null, array[i])); } + } } - return channels; + } } + return channels; + } } diff --git a/src/main/java/org/phoebus/channelfinder/example/PopulateService.java b/src/main/java/org/phoebus/channelfinder/example/PopulateService.java index ed067ec8..676bae81 100644 --- a/src/main/java/org/phoebus/channelfinder/example/PopulateService.java +++ b/src/main/java/org/phoebus/channelfinder/example/PopulateService.java @@ -9,14 +9,6 @@ import co.elastic.clients.elasticsearch.core.bulk.IndexOperation; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import org.phoebus.channelfinder.ElasticConfig; -import org.phoebus.channelfinder.entity.Channel; -import org.phoebus.channelfinder.entity.Property; -import org.phoebus.channelfinder.entity.Tag; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Configuration; - import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -33,699 +25,1366 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.phoebus.channelfinder.ElasticConfig; +import org.phoebus.channelfinder.entity.Channel; +import org.phoebus.channelfinder.entity.Property; +import org.phoebus.channelfinder.entity.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Configuration; /** * An class for creating the example database. - *

- * The createDB method can be invoked with a specified list of cells - * For each cell, there are 1500 channels - * The channel names follow the following convention - * {system}:{cell}-{device}-{signal} - *

- * systems: SR(1000) and BR(500) - * cell: C001 - * device: Magnets, Powersupply, BPMs,... - * signal: St or RB - *

- * e.g. BR:C001-MG:1{QDP:D}Fld-SP - *

- * Additionally, each channel has a list of tags and properties - *

- * Properties include: - * location, cell, element, device, family, unit, type, z_pos_r, mount, and some generic properties - * properties group[0-9] with values [0, 1, 2, 5, 10, 20, 50, 100, 200, 500] which matches the # of channels with those values - *

- * Tags include: - * group[0-9]_[count] with count values [0, 1, 2, 5, 10, 20, 50, 100, 200, 500] which matches the # of channels with those values + * + *

The createDB method can be invoked with a specified list of cells For each cell, there are + * 1500 channels The channel names follow the following convention {system}:{cell}-{device}-{signal} + * + *

systems: SR(1000) and BR(500) cell: C001 device: Magnets, Powersupply, BPMs,... signal: St or + * RB + * + *

e.g. BR:C001-MG:1{QDP:D}Fld-SP + * + *

Additionally, each channel has a list of tags and properties + * + *

Properties include: location, cell, element, device, family, unit, type, z_pos_r, mount, and + * some generic properties properties group[0-9] with values [0, 1, 2, 5, 10, 20, 50, 100, 200, 500] + * which matches the # of channels with those values + * + *

Tags include: group[0-9]_[count] with count values [0, 1, 2, 5, 10, 20, 50, 100, 200, 500] + * which matches the # of channels with those values * * @author Kunal Shroff */ @Configuration public class PopulateService { - private static final Logger logger = Logger.getLogger(PopulateService.class.getName()); - public static final String DEVICE_POWER_SUPPLY = "power supply"; - public static final String DEVICE_MAGNET = "magnet"; - public static final String UNIT_TEMP = "temperature"; - public static final String SIGTYPE_STATUS = "status"; - public static final String ELEMENT_VACUUM = "vacuum"; - public static final String UNIT_FIELD = "field"; - public static final String SIGTYPE_READBACK = "readback"; - public static final String SIGTYPE_SETPOINT = "setpoint"; - public static final String UNIT_CURRENT = "current"; - public static final String UNIT_POWER = "power"; - public static final String SIGTYPE_SWITCH = "switch"; - public static final String ELEMENT_TEMPERATURE_SENSOR = "temperature sensor"; - public static final String DEVICE_SENSOR = "sensor"; - public static final String PROPERTY_NAME_MOUNT = "mount"; - public static final String T_1_RB = "}T:1-RB"; - public static final String T_2_RB = "}T:2-RB"; - public static final String ON_ST = "}On-St"; - public static final String OK_ST = "}OK-St"; - public static final String GROUP = "group"; - - static int maxProp = 40; // must be >=20 - static int maxTag = 60; // must be >=11 - - // The number of cells can be increases to 100 - // Each cell would consist of a 1000 SR channels and 500 BO channels - private static int numberOfCells = 2; - - static String cowner = "testc"; - static String powner = "testp"; - static String towner = "testt"; - - public static final List valBucket = List.of(0, 1, 2, 5, 10, 20, 50, 100, 200, 500); - public static final List valBucketSize = List.of(1000 - valBucket.stream().mapToInt(Integer::intValue).sum(), 1, 2, 5, 10, 20, 50, 100, 200, 500); - - // A static list of props, tags, channels handled by this class which must be cleaned up on closure. - static Set propertySet = new HashSet<>(); - Set tagSet = new HashSet<>(); - Set channelList = new HashSet<>(); - - @Autowired - ElasticConfig esService; - - @Autowired - @Qualifier("indexClient") - ElasticsearchClient client; - - - public static final ObjectMapper mapper = new ObjectMapper(); - - - static int index; - - static List tokens1000 = new ArrayList<>(); - static List tokens500 = new ArrayList<>(); - - // Create a list of properties - static { - for (int i = 10; i < 70; i++) { - propertySet.add(new Property("prop" + String.format("%03d", i), powner)); - } + private static final Logger logger = Logger.getLogger(PopulateService.class.getName()); + public static final String DEVICE_POWER_SUPPLY = "power supply"; + public static final String DEVICE_MAGNET = "magnet"; + public static final String UNIT_TEMP = "temperature"; + public static final String SIGTYPE_STATUS = "status"; + public static final String ELEMENT_VACUUM = "vacuum"; + public static final String UNIT_FIELD = "field"; + public static final String SIGTYPE_READBACK = "readback"; + public static final String SIGTYPE_SETPOINT = "setpoint"; + public static final String UNIT_CURRENT = "current"; + public static final String UNIT_POWER = "power"; + public static final String SIGTYPE_SWITCH = "switch"; + public static final String ELEMENT_TEMPERATURE_SENSOR = "temperature sensor"; + public static final String DEVICE_SENSOR = "sensor"; + public static final String PROPERTY_NAME_MOUNT = "mount"; + public static final String T_1_RB = "}T:1-RB"; + public static final String T_2_RB = "}T:2-RB"; + public static final String ON_ST = "}On-St"; + public static final String OK_ST = "}OK-St"; + public static final String GROUP = "group"; + + static int maxProp = 40; // must be >=20 + static int maxTag = 60; // must be >=11 + + // The number of cells can be increases to 100 + // Each cell would consist of a 1000 SR channels and 500 BO channels + private static int numberOfCells = 2; + + static String cowner = "testc"; + static String powner = "testp"; + static String towner = "testt"; + + public static final List valBucket = List.of(0, 1, 2, 5, 10, 20, 50, 100, 200, 500); + public static final List valBucketSize = + List.of( + 1000 - valBucket.stream().mapToInt(Integer::intValue).sum(), + 1, + 2, + 5, + 10, + 20, + 50, + 100, + 200, + 500); + + // A static list of props, tags, channels handled by this class which must be cleaned up on + // closure. + static Set propertySet = new HashSet<>(); + Set tagSet = new HashSet<>(); + Set channelList = new HashSet<>(); + + @Autowired ElasticConfig esService; + + @Autowired + @Qualifier("indexClient") + ElasticsearchClient client; + + public static final ObjectMapper mapper = new ObjectMapper(); + + static int index; + + static List tokens1000 = new ArrayList<>(); + static List tokens500 = new ArrayList<>(); + + // Create a list of properties + static { + for (int i = 10; i < 70; i++) { + propertySet.add(new Property("prop" + String.format("%03d", i), powner)); + } - index = 0; - valBucketSize.forEach(count -> { - for (int i = 0; i < count; i++) { - tokens1000.add(valBucket.get(index)); - } - index++; + index = 0; + valBucketSize.forEach( + count -> { + for (int i = 0; i < count; i++) { + tokens1000.add(valBucket.get(index)); + } + index++; }); - index = 0; - valBucketSize.forEach(count -> { - for (int i = 0; i < count; i++) { - tokens500.add(valBucket.get(index)); - } - index++; + index = 0; + valBucketSize.forEach( + count -> { + for (int i = 0; i < count; i++) { + tokens500.add(valBucket.get(index)); + } + index++; }); - } - - public synchronized void cleanupDB() { - BulkRequest.Builder br = new BulkRequest.Builder(); - for (String channelName : channelList) { - br.operations(op -> op - .delete(idx -> idx - .index(esService.getES_CHANNEL_INDEX()) - .id(channelName) - ) - ); - } - for (Tag tag : tagSet) { - br.operations(op -> op - .delete(idx -> idx - .index(esService.getES_TAG_INDEX()) - .id(tag.getName()) - ) - ); - } - for (Property property : propertySet) { - br.operations(op -> op - .delete(idx -> idx - .index(esService.getES_PROPERTY_INDEX()) - .id(property.getName()) - ) - ); - } - try { - BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); - if (result.errors()) { - logger.log(Level.SEVERE, "CleanupDb Bulk had errors"); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } - } catch (IOException e) { - logger.log(Level.WARNING, e.getMessage(), e); - } - } + } - public synchronized void createDB(int cells) { - numberOfCells = cells; - createDB(); + public synchronized void cleanupDB() { + BulkRequest.Builder br = new BulkRequest.Builder(); + for (String channelName : channelList) { + br.operations( + op -> op.delete(idx -> idx.index(esService.getES_CHANNEL_INDEX()).id(channelName))); } - - public Set getChannelList() { - return channelList; + for (Tag tag : tagSet) { + br.operations( + op -> op.delete(idx -> idx.index(esService.getES_TAG_INDEX()).id(tag.getName()))); } - - public synchronized void createDB() { - int freq = 25; - Collection channels = new ArrayList<>(); - createSRChannels(channels, freq); - createBOChannels(channels, freq); - bulkInsertAllChannels(channels); - propertySet.forEach(p -> - logger.log(Level.INFO, p.toLog()) - ); - tagSet.forEach(t -> - logger.log(Level.INFO, t.toLog()) - ); - - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Property property : propertySet) { - br.operations(op -> op.index(bIndex -> bIndex.index(esService.getES_PROPERTY_INDEX()).id(property.getName()).document(property))); - } - for (Tag tag : tagSet) { - br.operations(op -> op.index(bIndex -> bIndex.index(esService.getES_TAG_INDEX()).id(tag.getName()).document(tag))); - } - br.refresh(Refresh.True); - - checkBulkResponse(br); - logger.log(Level.INFO, "completed populating"); + for (Property property : propertySet) { + br.operations( + op -> + op.delete(idx -> idx.index(esService.getES_PROPERTY_INDEX()).id(property.getName()))); } - - private void checkBulkResponse(BulkRequest.Builder br) { - try { - BulkResponse results = client.bulk(br.build()); - if (results.errors()) { - logger.log(Level.SEVERE, "CreateDB Bulk had errors"); - for (BulkResponseItem item : results.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } - } catch (IOException e) { - logger.log(Level.WARNING, "CreateDB Bulk operation failed.", e); + try { + BulkResponse result = client.bulk(br.refresh(Refresh.True).build()); + if (result.errors()) { + logger.log(Level.SEVERE, "CleanupDb Bulk had errors"); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } + } + } catch (IOException e) { + logger.log(Level.WARNING, e.getMessage(), e); } - - private void bulkInsertAllChannels(Collection channels) { - try { - logger.info("Bulk inserting channels"); - - bulkInsertChannels(channels); - channels.clear(); - - } catch (Exception e) { - logger.log(Level.WARNING, e.getMessage(), e); - } + } + + public synchronized void createDB(int cells) { + numberOfCells = cells; + createDB(); + } + + public Set getChannelList() { + return channelList; + } + + public synchronized void createDB() { + int freq = 25; + Collection channels = new ArrayList<>(); + createSRChannels(channels, freq); + createBOChannels(channels, freq); + bulkInsertAllChannels(channels); + propertySet.forEach(p -> logger.log(Level.INFO, p.toLog())); + tagSet.forEach(t -> logger.log(Level.INFO, t.toLog())); + + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Property property : propertySet) { + br.operations( + op -> + op.index( + bIndex -> + bIndex + .index(esService.getES_PROPERTY_INDEX()) + .id(property.getName()) + .document(property))); } - - private void createBOChannels(Collection channels, int freq) { - logger.info(() -> "Creating BO channels"); - - for (int i = 1; i <= numberOfCells; i++) { - - String cell = String.format("%03d", i); - channels.addAll(insertBOCell(cell)); - - if (i % freq == 0) { - bulkInsertAllChannels(channels); - } - } + for (Tag tag : tagSet) { + br.operations( + op -> + op.index( + bIndex -> + bIndex.index(esService.getES_TAG_INDEX()).id(tag.getName()).document(tag))); } - - private void createSRChannels(Collection channels, int freq) { - logger.info("Creating SR channels"); - - for (int i = 1; i <= numberOfCells; i++) { - String cell = String.format("%03d", i); - channels.addAll(insertSRCell(cell)); - if (i % freq == 0) { - bulkInsertAllChannels(channels); - } + br.refresh(Refresh.True); + + checkBulkResponse(br); + logger.log(Level.INFO, "completed populating"); + } + + private void checkBulkResponse(BulkRequest.Builder br) { + try { + BulkResponse results = client.bulk(br.build()); + if (results.errors()) { + logger.log(Level.SEVERE, "CreateDB Bulk had errors"); + for (BulkResponseItem item : results.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } } + } + } catch (IOException e) { + logger.log(Level.WARNING, "CreateDB Bulk operation failed.", e); } + } + private void bulkInsertAllChannels(Collection channels) { + try { + logger.info("Bulk inserting channels"); - public void createTagsAndProperties(URL tagResource, URL propertyResource) { - // Setup the default tags - String tagsURL; - tagsURL = tagResource.toExternalForm(); - try (InputStream input = new URL(tagsURL).openStream() ) { - List jsonTag = mapper.readValue(input, new TypeReference>(){}); - - jsonTag.forEach(tag -> { - try { - if(!client.exists(e -> e.index(esService.getES_TAG_INDEX()).id(tag.getName())).value()){ - IndexRequest indexRequest = - IndexRequest.of(i -> - i.index(esService.getES_TAG_INDEX()) - .id(tag.getName()) - .document(tag) - .refresh(Refresh.True)); - client.index(indexRequest); - } - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to initialize tag : " +tag.getName(), e); - } - }); - } catch (IOException ex) { - logger.log(Level.WARNING, "Failed to initialize tag ", ex); - } + bulkInsertChannels(channels); + channels.clear(); - // Setup the default properties - String propertiesURL; - propertiesURL = propertyResource.toExternalForm(); - try (InputStream input = new URL(propertiesURL).openStream() ) { - List jsonTag = mapper.readValue(input, new TypeReference<>() { - }); - - jsonTag.forEach(property -> { - try { - if(!client.exists(e -> e.index(esService.getES_PROPERTY_INDEX()).id(property.getName())).value()){ - IndexRequest indexRequest = - IndexRequest.of(i -> - i.index(esService.getES_PROPERTY_INDEX()) - .id(property.getName()) - .document(property) - .refresh(Refresh.True)); - client.index(indexRequest); - } - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to initialize property : " +property.getName(), e); - } - }); - } catch (IOException ex) { - logger.log(Level.WARNING, "Failed to initialize property ", ex); - } + } catch (Exception e) { + logger.log(Level.WARNING, e.getMessage(), e); } - private Collection insertSRCell(String cell) { - String loc = "storage ring"; - String pre = "SR:C"; - // Tokens - Map> tokens = new HashMap<>(); - for (int i = 0; i < 6; i++) { - tokens.put(i, new ArrayList<>(tokens1000)); - } - - AtomicInteger channelCounter = new AtomicInteger(0); - - Collection result = new ArrayList<>(1000); - result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "DP", loc, cell, "dipole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 5, pre, "QDP:D", loc, cell, "defocusing quadrupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 5, pre, "QDP:F", loc, cell, "focusing quadrupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "QDP:S", loc, cell, "skew quadrupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "STP", loc, cell, "sextupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 5, pre, "HC:S", loc, cell, "horizontal slow corrector")); - result.addAll(insertAirMagnets(tokens, channelCounter, 5, pre, "HC:F", loc, cell, "horizontal fast corrector")); - result.addAll(insertBigMagnets(tokens, channelCounter, 5, pre, "VC:S", loc, cell, "vertical slow corrector")); - result.addAll(insertAirMagnets(tokens, channelCounter, 4, pre, "VC:F", loc, cell, "vertical fast corrector")); - - result.addAll(insertValves(tokens, channelCounter, 5, pre, loc, cell)); - - result.addAll(insertGauges(tokens, channelCounter, 5, pre, "VGC", loc, cell)); - result.addAll(insertGauges(tokens, channelCounter, 5, pre, "TCG", loc, cell)); - - result.addAll(insertPumps(tokens, channelCounter, pre, "IPC", loc, cell)); - result.addAll(insertPumps(tokens, channelCounter, pre, "TMP", loc, cell)); + } - result.addAll(insertTemps(tokens, channelCounter, 40, pre, loc, cell)); + private void createBOChannels(Collection channels, int freq) { + logger.info(() -> "Creating BO channels"); - result.addAll(insertBpms(tokens, channelCounter, 4, pre, "BSA", loc, cell, "small aperture BPM")); - result.addAll(insertBpms(tokens, channelCounter, 4, pre, "BHS", loc, cell, "high stability BPM")); - result.addAll(insertBpms(tokens, channelCounter, 4, pre, "BLA", loc, cell, "large aperture BPM")); + for (int i = 1; i <= numberOfCells; i++) { - return result; - } + String cell = String.format("%03d", i); + channels.addAll(insertBOCell(cell)); - private void bulkInsertChannels(Collection result) throws IOException { - long start = System.currentTimeMillis(); - BulkRequest.Builder br = new BulkRequest.Builder(); - for (Channel channel : result) { - br.operations(op -> op.index(IndexOperation.of(i -> i.index(esService.getES_CHANNEL_INDEX()).id(channel.getName()).document(channel)))); - } - String prepare = "|Prepare: " + (System.currentTimeMillis() - start) + "|"; - start = System.currentTimeMillis(); - br.refresh(Refresh.True); - - BulkResponse srResult = client.bulk(br.build()); - String execute = "|Execute: " + (System.currentTimeMillis() - start) + "|"; - logger.log(Level.INFO, () -> "Inserted cell " + prepare + " " + execute); - if (srResult.errors()) { - logger.log(Level.SEVERE, "Bulk insert had errors"); - for (BulkResponseItem item : srResult.items()) { - if (item.error() != null) { - logger.log(Level.SEVERE, () -> item.error().reason()); - } - } - } + if (i % freq == 0) { + bulkInsertAllChannels(channels); + } } + } - private Collection insertBOCell(String cell) { - String loc = "booster"; - String pre = "BR:C"; - - // Tokens - Map> tokens = new HashMap<>(); - for (int i = 0; i < 6; i++) { - tokens.put(i, new ArrayList<>(tokens500)); - } + private void createSRChannels(Collection channels, int freq) { + logger.info("Creating SR channels"); - AtomicInteger channelCounter = new AtomicInteger(0); - - Collection result = new ArrayList<>(500); - - result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "DP", loc, cell, "dipole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "QDP:D", loc, cell, "defocusing quadrupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "QDP:F", loc, cell, "focusing quadrupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "STP", loc, cell, "sextupole")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "HC", loc, cell, "horizontal corrector")); - result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "VC", loc, cell, "vertical corrector")); - - result.addAll(insertValves(tokens, channelCounter, 4, pre, loc, cell)); - - result.addAll(insertGauges(tokens, channelCounter, 4, pre, "VGC", loc, cell)); - result.addAll(insertGauges(tokens, channelCounter, 2, pre, "TCG", loc, cell)); - - result.addAll(insertPumps(tokens, channelCounter, pre, "IPC", loc, cell)); - result.addAll(insertPumps(tokens, channelCounter, pre, "TMP", loc, cell)); - - result.addAll(insertTemps(tokens, channelCounter, 10, pre, loc, cell)); - - result.addAll(insertBpms(tokens, channelCounter, 2, pre, "BLA", loc, cell, "beam position monitor")); - return result; + for (int i = 1; i <= numberOfCells; i++) { + String cell = String.format("%03d", i); + channels.addAll(insertSRCell(cell)); + if (i % freq == 0) { + bulkInsertAllChannels(channels); + } } - - private Collection insertBigMagnets(Map> tokens, AtomicInteger channelInCell, int count, String prefix, - String dev, String loc, String cell, String element) { - ArrayList channels = new ArrayList<>(); - insertPowerSupplyChannels(channels, tokens, channelInCell, count, prefix, dev, loc, cell, element); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}T-St", loc, cell, element, DEVICE_POWER_SUPPLY, UNIT_TEMP, SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}F-St", loc, cell, element, DEVICE_POWER_SUPPLY, "water flow", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}Gnd-St", loc, cell, element, DEVICE_POWER_SUPPLY, "ground", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}Ctl-St", loc, cell, element, DEVICE_POWER_SUPPLY, "control", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}Val-St", loc, cell, element, DEVICE_POWER_SUPPLY, "value", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}Fld-RB", loc, cell, element, DEVICE_MAGNET, UNIT_FIELD, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}Fld-SP", loc, cell, element, DEVICE_MAGNET, UNIT_FIELD, SIGTYPE_SETPOINT)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + T_1_RB, loc, cell, element, DEVICE_MAGNET, UNIT_TEMP, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + T_2_RB, loc, cell, element, DEVICE_MAGNET, UNIT_TEMP, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}F-RB", loc, cell, element, DEVICE_MAGNET, "water flow", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}F:in-St", loc, cell, element, DEVICE_MAGNET, "water flow in", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}F:out-St", loc, cell, element, DEVICE_MAGNET, "water flow out", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}F:dif-St", loc, cell, element, DEVICE_MAGNET, "water flow diff", SIGTYPE_STATUS)); - return channels; + } + + public void createTagsAndProperties(URL tagResource, URL propertyResource) { + // Setup the default tags + String tagsURL; + tagsURL = tagResource.toExternalForm(); + try (InputStream input = new URL(tagsURL).openStream()) { + List jsonTag = mapper.readValue(input, new TypeReference>() {}); + + jsonTag.forEach( + tag -> { + try { + if (!client + .exists(e -> e.index(esService.getES_TAG_INDEX()).id(tag.getName())) + .value()) { + IndexRequest indexRequest = + IndexRequest.of( + i -> + i.index(esService.getES_TAG_INDEX()) + .id(tag.getName()) + .document(tag) + .refresh(Refresh.True)); + client.index(indexRequest); + } + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to initialize tag : " + tag.getName(), e); + } + }); + } catch (IOException ex) { + logger.log(Level.WARNING, "Failed to initialize tag ", ex); } - private void insertPowerSupplyChannels(ArrayList channels, Map> tokens, AtomicInteger channelInCell, int count, String prefix, String dev, String loc, String cell, String element) { - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}I-RB", loc, cell, element, DEVICE_POWER_SUPPLY, UNIT_CURRENT, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}I-SP", loc, cell, element, DEVICE_POWER_SUPPLY, UNIT_CURRENT, SIGTYPE_SETPOINT)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}On-Sw", loc, cell, element, DEVICE_POWER_SUPPLY, UNIT_POWER, SIGTYPE_SWITCH)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}Rst-Cmd", loc, cell, element, DEVICE_POWER_SUPPLY, "reset", "command")); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + ON_ST, loc, cell, element, DEVICE_POWER_SUPPLY, UNIT_POWER, SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + "}Acc-St", loc, cell, element, DEVICE_POWER_SUPPLY, "access", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PS:", "{" + dev + OK_ST, loc, cell, element, DEVICE_POWER_SUPPLY, "sum error", SIGTYPE_STATUS)); + // Setup the default properties + String propertiesURL; + propertiesURL = propertyResource.toExternalForm(); + try (InputStream input = new URL(propertiesURL).openStream()) { + List jsonTag = mapper.readValue(input, new TypeReference<>() {}); + + jsonTag.forEach( + property -> { + try { + if (!client + .exists(e -> e.index(esService.getES_PROPERTY_INDEX()).id(property.getName())) + .value()) { + IndexRequest indexRequest = + IndexRequest.of( + i -> + i.index(esService.getES_PROPERTY_INDEX()) + .id(property.getName()) + .document(property) + .refresh(Refresh.True)); + client.index(indexRequest); + } + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to initialize property : " + property.getName(), e); + } + }); + } catch (IOException ex) { + logger.log(Level.WARNING, "Failed to initialize property ", ex); } - - private Collection insertAirMagnets(Map> tokens, AtomicInteger channelInCell, int count, String prefix, String dev, String loc, String cell, String element) { - ArrayList channels = new ArrayList<>(); - insertPowerSupplyChannels(channels, tokens, channelInCell, count, prefix, dev, loc, cell, element); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}Fld-RB", loc, cell, element, DEVICE_MAGNET, UNIT_FIELD, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}Fld-SP", loc, cell, element, DEVICE_MAGNET, UNIT_FIELD, SIGTYPE_SETPOINT)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "MG:", "{" + dev + "}T-RB", loc, cell, element, DEVICE_MAGNET, UNIT_TEMP, SIGTYPE_READBACK)); - return channels; + } + + private Collection insertSRCell(String cell) { + String loc = "storage ring"; + String pre = "SR:C"; + // Tokens + Map> tokens = new HashMap<>(); + for (int i = 0; i < 6; i++) { + tokens.put(i, new ArrayList<>(tokens1000)); } - - private Collection insertValves(Map> tokens, AtomicInteger channelInCell, int count, String prefix, String loc, String cell) { - ArrayList channels = new ArrayList<>(); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "VA:", "{" + "GV" + "}Opn-Sw", loc, cell, PopulateService.ELEMENT_VACUUM, "valve", "position", SIGTYPE_SWITCH)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "VA:", "{" + "GV" + "}Opn-St", loc, cell, PopulateService.ELEMENT_VACUUM, "valve", "position", SIGTYPE_STATUS)); - return channels; + AtomicInteger channelCounter = new AtomicInteger(0); + + Collection result = new ArrayList<>(1000); + result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "DP", loc, cell, "dipole")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 5, pre, "QDP:D", loc, cell, "defocusing quadrupole")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 5, pre, "QDP:F", loc, cell, "focusing quadrupole")); + result.addAll( + insertBigMagnets(tokens, channelCounter, 4, pre, "QDP:S", loc, cell, "skew quadrupole")); + result.addAll(insertBigMagnets(tokens, channelCounter, 4, pre, "STP", loc, cell, "sextupole")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 5, pre, "HC:S", loc, cell, "horizontal slow corrector")); + result.addAll( + insertAirMagnets( + tokens, channelCounter, 5, pre, "HC:F", loc, cell, "horizontal fast corrector")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 5, pre, "VC:S", loc, cell, "vertical slow corrector")); + result.addAll( + insertAirMagnets( + tokens, channelCounter, 4, pre, "VC:F", loc, cell, "vertical fast corrector")); + + result.addAll(insertValves(tokens, channelCounter, 5, pre, loc, cell)); + + result.addAll(insertGauges(tokens, channelCounter, 5, pre, "VGC", loc, cell)); + result.addAll(insertGauges(tokens, channelCounter, 5, pre, "TCG", loc, cell)); + + result.addAll(insertPumps(tokens, channelCounter, pre, "IPC", loc, cell)); + result.addAll(insertPumps(tokens, channelCounter, pre, "TMP", loc, cell)); + + result.addAll(insertTemps(tokens, channelCounter, 40, pre, loc, cell)); + + result.addAll( + insertBpms(tokens, channelCounter, 4, pre, "BSA", loc, cell, "small aperture BPM")); + result.addAll( + insertBpms(tokens, channelCounter, 4, pre, "BHS", loc, cell, "high stability BPM")); + result.addAll( + insertBpms(tokens, channelCounter, 4, pre, "BLA", loc, cell, "large aperture BPM")); + + return result; + } + + private void bulkInsertChannels(Collection result) throws IOException { + long start = System.currentTimeMillis(); + BulkRequest.Builder br = new BulkRequest.Builder(); + for (Channel channel : result) { + br.operations( + op -> + op.index( + IndexOperation.of( + i -> + i.index(esService.getES_CHANNEL_INDEX()) + .id(channel.getName()) + .document(channel)))); } - - private Collection insertGauges(Map> tokens, AtomicInteger channelInCell, int count, String prefix, String dev, String loc, String cell) { - List channels = new ArrayList<>(); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "VA:", "{" + dev + "}P-RB", loc, cell, PopulateService.ELEMENT_VACUUM, "gauge", "pressure", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "VA:", "{" + dev + OK_ST, loc, cell, PopulateService.ELEMENT_VACUUM, "gauge", "error", SIGTYPE_STATUS)); - return channels; - } - - - private Collection insertPumps(Map> tokens, AtomicInteger channelInCell, String prefix, - String dev, String loc, String cell) { - List channels = new ArrayList<>(); - channels.addAll(insertBunch(tokens, channelInCell, 2, prefix, "VA:", "{" + dev + "}I-RB", loc, cell, PopulateService.ELEMENT_VACUUM, "pump", UNIT_CURRENT, SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, 2, prefix, "VA:", "{" + dev + "}P-RB", loc, cell, PopulateService.ELEMENT_VACUUM, "pump", "pressure", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, 2, prefix, "VA:", "{" + dev + "}On-Sw", loc, cell, PopulateService.ELEMENT_VACUUM, "pump", UNIT_POWER, SIGTYPE_SWITCH)); - channels.addAll(insertBunch(tokens, channelInCell, 2, prefix, "VA:", "{" + dev + OK_ST, loc, cell, PopulateService.ELEMENT_VACUUM, "pump", "error", SIGTYPE_STATUS)); - channels.addAll(insertBunch(tokens, channelInCell, 2, prefix, "VA:", "{" + dev + ON_ST, loc, cell, PopulateService.ELEMENT_VACUUM, "pump", UNIT_POWER, SIGTYPE_STATUS)); - return channels; + String prepare = "|Prepare: " + (System.currentTimeMillis() - start) + "|"; + start = System.currentTimeMillis(); + br.refresh(Refresh.True); + + BulkResponse srResult = client.bulk(br.build()); + String execute = "|Execute: " + (System.currentTimeMillis() - start) + "|"; + logger.log(Level.INFO, () -> "Inserted cell " + prepare + " " + execute); + if (srResult.errors()) { + logger.log(Level.SEVERE, "Bulk insert had errors"); + for (BulkResponseItem item : srResult.items()) { + if (item.error() != null) { + logger.log(Level.SEVERE, () -> item.error().reason()); + } + } } + } - private Collection insertTemps(Map> tokens, AtomicInteger channelInCell, int count, String prefix, - String loc, String cell) { - List channels = new ArrayList<>(); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PU:T", "{" + "TC" + T_1_RB, loc, cell, ELEMENT_TEMPERATURE_SENSOR, DEVICE_SENSOR, "temperature 1", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PU:T", "{" + "TC" + T_2_RB, loc, cell, ELEMENT_TEMPERATURE_SENSOR, DEVICE_SENSOR, "temperature 2", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PU:T", "{" + "TC" + "}T:3-RB", loc, cell, ELEMENT_TEMPERATURE_SENSOR, DEVICE_SENSOR, "temperature 3", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PU:T", "{" + "TC" + "}T:4-RB", loc, cell, ELEMENT_TEMPERATURE_SENSOR, DEVICE_SENSOR, "temperature 4", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "PU:T", "{" + "TC" + ON_ST, loc, cell, ELEMENT_TEMPERATURE_SENSOR, DEVICE_SENSOR, UNIT_POWER, SIGTYPE_STATUS)); - return channels; - } + private Collection insertBOCell(String cell) { + String loc = "booster"; + String pre = "BR:C"; - private Collection insertBpms(Map> tokens, AtomicInteger channelInCell, int count, String prefix, String dev, - String loc, String cell, String element) { - List channels = new ArrayList<>(); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "BI:", "{" + dev + "}Pos:X-RB", loc, cell, element, "bpm", "x position", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "BI:", "{" + dev + "}Pos:Y-RB", loc, cell, element, "bpm", "y position", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "BI:", "{" + dev + "}Sig:X-RB", loc, cell, element, "bpm", "x sigma", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "BI:", "{" + dev + "}Sig:Y-RB", loc, cell, element, "bpm", "y sigma", SIGTYPE_READBACK)); - channels.addAll(insertBunch(tokens, channelInCell, count, prefix, "BI:", "{" + dev + ON_ST, loc, cell, element, "bpm", UNIT_POWER, SIGTYPE_STATUS)); - return channels; + // Tokens + Map> tokens = new HashMap<>(); + for (int i = 0; i < 6; i++) { + tokens.put(i, new ArrayList<>(tokens500)); } - private Collection insertBunch(Map> tokens, AtomicInteger channelInCellCounter, int count, String prefix, - String midfix, String postfix, String location, String cell, String element, String device, String unit, - String sigtype) { - int cw = count > 9 ? 2 : 1; - List result = new ArrayList<>(count); - for (int i = 1; i < count + 1; i++) { - Channel channel; - if (count == 1) { - channel = new Channel(prefix + cell + "-" + midfix + postfix, cowner); - } else { - channel = new Channel(prefix + cell + "-" + midfix + String.format("%0" + cw + "d", i) + postfix, - cowner); - } - int channelInCell = channelInCellCounter.getAndIncrement(); - - channel.getProperties().add(new Property("location", powner, location)); - channel.getProperties().add(new Property("cell", powner, cell)); - channel.getProperties().add(new Property("element", powner, element)); - channel.getProperties().add(new Property("device", powner, device)); - if (count != 1) { - channel.getProperties().add(new Property("family", powner, String.format("%0" + cw + "d", i))); - } - channel.getProperties().add(new Property("unit", powner, unit)); - channel.getProperties().add(new Property("type", powner, sigtype)); - - String posC = String.format("%03d", Math.round((10.0 / (count + 1)) * i)); - channel.getProperties().add(new Property("z_pos_r", powner, posC)); - - if (postfix.endsWith(T_1_RB)) { - channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "outside")); - } else if (postfix.endsWith(T_2_RB)) { - channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "inside")); - } else if (postfix.endsWith("}T:3-RB")) { - channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "top")); - } else if (postfix.endsWith("}T:4-RB")) { - channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "bottom")); - } else { - channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "center")); - } - - for (Entry> entry : tokens.entrySet()) { - // pop val from the tokens - int randIndex = ThreadLocalRandom.current().nextInt(entry.getValue().size()); - Integer val = entry.getValue().remove(randIndex); - channel.getProperties().add(new Property("group" + entry.getKey(), powner, String.valueOf(val))); - channel.getTags().add(new Tag("group" + entry.getKey() + "_" + val, towner)); - } - - String group = GROUP + 6; - if (channelInCell % 2 == 1) { - channel.getProperties().add(new Property(group, powner, "500")); - channel.getTags().add(new Tag(group + "_500", towner)); - } else if (channelInCell < 2 * 200) { - channel.getProperties().add(new Property(group, powner, "200")); - channel.getTags().add(new Tag(group + "_200", towner)); - } else if (channelInCell < 2 * (200 + 100)) { - channel.getProperties().add(new Property(group, powner, "100")); - channel.getTags().add(new Tag(group + "_100", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50)) { - channel.getProperties().add(new Property(group, powner, "50")); - channel.getTags().add(new Tag(group + "_50", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50 + 20)) { - channel.getProperties().add(new Property(group, powner, "20")); - channel.getTags().add(new Tag(group + "_20", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10)) { - channel.getProperties().add(new Property(group, powner, "10")); - channel.getTags().add(new Tag(group + "_10", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5)) { - channel.getProperties().add(new Property(group, powner, "5")); - channel.getTags().add(new Tag(group + "_5", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2)) { - channel.getProperties().add(new Property(group, powner, "2")); - channel.getTags().add(new Tag(group + "_2", towner)); - } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { - channel.getProperties().add(new Property(group, powner, "1")); - channel.getTags().add(new Tag(group + "_1", towner)); - } else { - channel.getProperties().add(new Property(group, powner, "0")); - channel.getTags().add(new Tag(group + "_0", towner)); - } - - group = GROUP + 7; - if (channelInCell % 2 == 0) { - channel.getProperties().add(new Property(group, powner, String.valueOf(500))); - channel.getTags().add(new Tag(group + "_500", towner)); - } else if (channelInCell <= 2 * 200) { - channel.getProperties().add(new Property(group, powner, "200")); - channel.getTags().add(new Tag(group + "_200", towner)); - } else if (channelInCell <= 2 * (200 + 100)) { - channel.getProperties().add(new Property(group, powner, "100")); - channel.getTags().add(new Tag(group + "_100", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50)) { - channel.getProperties().add(new Property(group, powner, "50")); - channel.getTags().add(new Tag(group + "_50", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50 + 20)) { - channel.getProperties().add(new Property(group, powner, "20")); - channel.getTags().add(new Tag(group + "_20", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10)) { - channel.getProperties().add(new Property(group, powner, "10")); - channel.getTags().add(new Tag(group + "_10", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5)) { - channel.getProperties().add(new Property(group, powner, "5")); - channel.getTags().add(new Tag(group + "_5", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2)) { - channel.getProperties().add(new Property(group, powner, "2")); - channel.getTags().add(new Tag(group + "_2", towner)); - } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { - channel.getProperties().add(new Property(group, powner, "1")); - channel.getTags().add(new Tag(group + "_1", towner)); - } else { - channel.getProperties().add(new Property(group, powner, "0")); - channel.getTags().add(new Tag(group + "_0", towner)); - } - - group = GROUP + 8; - if (channelInCell < 500) { - channel.getProperties().add(new Property(group, powner, String.valueOf(500))); - channel.getTags().add(new Tag(group + "_500", towner)); - } else if (channelInCell < 500 + 200) { - channel.getProperties().add(new Property(group, powner, "200")); - channel.getTags().add(new Tag(group + "_200", towner)); - } else if (channelInCell < 500 + (200 + 100)) { - channel.getProperties().add(new Property(group, powner, "100")); - channel.getTags().add(new Tag(group + "_100", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50)) { - channel.getProperties().add(new Property(group, powner, "50")); - channel.getTags().add(new Tag(group + "_50", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50 + 20)) { - channel.getProperties().add(new Property(group, powner, "20")); - channel.getTags().add(new Tag(group + "_20", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10)) { - channel.getProperties().add(new Property(group, powner, "10")); - channel.getTags().add(new Tag(group + "_10", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5)) { - channel.getProperties().add(new Property(group, powner, "5")); - channel.getTags().add(new Tag(group + "_5", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5 + 2)) { - channel.getProperties().add(new Property(group, powner, "2")); - channel.getTags().add(new Tag(group + "_2", towner)); - } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { - channel.getProperties().add(new Property(group, powner, "1")); - channel.getTags().add(new Tag(group + "_1", towner)); - } else { - channel.getProperties().add(new Property(group, powner, "0")); - channel.getTags().add(new Tag(group + "_0", towner)); - } - - group = GROUP + 9; - if (channelInCell >= 500) { - channel.getProperties().add(new Property(group, powner, String.valueOf(500))); - channel.getTags().add(new Tag(group + "_500", towner)); - } else if (channelInCell >= 500 - 200) { - channel.getProperties().add(new Property(group, powner, "200")); - channel.getTags().add(new Tag(group + "_200", towner)); - } else if (channelInCell >= 500 - 200 - 100) { - channel.getProperties().add(new Property(group, powner, "100")); - channel.getTags().add(new Tag(group + "_100", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50) { - channel.getProperties().add(new Property(group, powner, "50")); - channel.getTags().add(new Tag(group + "_50", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50 - 20) { - channel.getProperties().add(new Property(group, powner, "20")); - channel.getTags().add(new Tag(group + "_20", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10) { - channel.getProperties().add(new Property(group, powner, "10")); - channel.getTags().add(new Tag(group + "_10", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5) { - channel.getProperties().add(new Property(group, powner, "5")); - channel.getTags().add(new Tag(group + "_5", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5 - 2) { - channel.getProperties().add(new Property(group, powner, "2")); - channel.getTags().add(new Tag(group + "_2", towner)); - } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5 - 2 - 1) { - channel.getProperties().add(new Property(group, powner, "1")); - channel.getTags().add(new Tag(group + "_1", towner)); - } else { - channel.getProperties().add(new Property(group, powner, "0")); - channel.getTags().add(new Tag(group + "_0", towner)); - } - - for (int j = 20; j < maxProp; j++) { - channel.getProperties().add(new Property("prop" + String.format("%02d", j), powner, - channelInCell + "-" + String.format("%02d", j))); - } - for (int k = 11; k < maxTag; k++) { - channel.getTags().add(new Tag("tag" + String.format("%02d", k), towner)); - } - int cellCount = Integer.parseInt(cell); - if (cellCount % 9 == 0) { - channel.getTags().add(new Tag("tagnine", towner)); - } else if (cellCount % 8 == 0) { - channel.getTags().add(new Tag("tageight", towner)); - } else if (cellCount % 7 == 0) { - channel.getTags().add(new Tag("tagseven", towner)); - } else if (cellCount % 6 == 0) { - channel.getTags().add(new Tag("tagsix", towner)); - } else if (cellCount % 5 == 0) { - channel.getTags().add(new Tag("tagfive", towner)); - } else if (cellCount % 4 == 0) { - channel.getTags().add(new Tag("tagfour", towner)); - } else if (cellCount % 3 == 0) { - channel.getTags().add(new Tag("tagthree", towner)); - } else if (cellCount % 2 == 0) { - channel.getTags().add(new Tag("tagtwo", towner)); - } else { - channel.getTags().add(new Tag("tagone", towner)); - } - - channelList.add(channel.getName()); - propertySet.addAll(channel.getProperties().stream().map(p -> - new Property(p.getName(), p.getOwner()) - ).collect(Collectors.toSet())); - tagSet.addAll(channel.getTags()); - result.add(channel); - } - return result; + AtomicInteger channelCounter = new AtomicInteger(0); + + Collection result = new ArrayList<>(500); + + result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "DP", loc, cell, "dipole")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 4, pre, "QDP:D", loc, cell, "defocusing quadrupole")); + result.addAll( + insertBigMagnets( + tokens, channelCounter, 4, pre, "QDP:F", loc, cell, "focusing quadrupole")); + result.addAll(insertBigMagnets(tokens, channelCounter, 2, pre, "STP", loc, cell, "sextupole")); + result.addAll( + insertBigMagnets(tokens, channelCounter, 4, pre, "HC", loc, cell, "horizontal corrector")); + result.addAll( + insertBigMagnets(tokens, channelCounter, 4, pre, "VC", loc, cell, "vertical corrector")); + + result.addAll(insertValves(tokens, channelCounter, 4, pre, loc, cell)); + + result.addAll(insertGauges(tokens, channelCounter, 4, pre, "VGC", loc, cell)); + result.addAll(insertGauges(tokens, channelCounter, 2, pre, "TCG", loc, cell)); + + result.addAll(insertPumps(tokens, channelCounter, pre, "IPC", loc, cell)); + result.addAll(insertPumps(tokens, channelCounter, pre, "TMP", loc, cell)); + + result.addAll(insertTemps(tokens, channelCounter, 10, pre, loc, cell)); + + result.addAll( + insertBpms(tokens, channelCounter, 2, pre, "BLA", loc, cell, "beam position monitor")); + return result; + } + + private Collection insertBigMagnets( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String dev, + String loc, + String cell, + String element) { + ArrayList channels = new ArrayList<>(); + insertPowerSupplyChannels( + channels, tokens, channelInCell, count, prefix, dev, loc, cell, element); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}T-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + UNIT_TEMP, + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}F-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "water flow", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}Gnd-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "ground", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}Ctl-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "control", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}Val-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "value", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}Fld-RB", + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_FIELD, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}Fld-SP", + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_FIELD, + SIGTYPE_SETPOINT)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + T_1_RB, + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_TEMP, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + T_2_RB, + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_TEMP, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}F-RB", + loc, + cell, + element, + DEVICE_MAGNET, + "water flow", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}F:in-St", + loc, + cell, + element, + DEVICE_MAGNET, + "water flow in", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}F:out-St", + loc, + cell, + element, + DEVICE_MAGNET, + "water flow out", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}F:dif-St", + loc, + cell, + element, + DEVICE_MAGNET, + "water flow diff", + SIGTYPE_STATUS)); + return channels; + } + + private void insertPowerSupplyChannels( + ArrayList channels, + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String dev, + String loc, + String cell, + String element) { + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}I-RB", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + UNIT_CURRENT, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}I-SP", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + UNIT_CURRENT, + SIGTYPE_SETPOINT)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}On-Sw", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + UNIT_POWER, + SIGTYPE_SWITCH)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}Rst-Cmd", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "reset", + "command")); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + ON_ST, + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + UNIT_POWER, + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + "}Acc-St", + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "access", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PS:", + "{" + dev + OK_ST, + loc, + cell, + element, + DEVICE_POWER_SUPPLY, + "sum error", + SIGTYPE_STATUS)); + } + + private Collection insertAirMagnets( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String dev, + String loc, + String cell, + String element) { + ArrayList channels = new ArrayList<>(); + insertPowerSupplyChannels( + channels, tokens, channelInCell, count, prefix, dev, loc, cell, element); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}Fld-RB", + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_FIELD, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}Fld-SP", + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_FIELD, + SIGTYPE_SETPOINT)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "MG:", + "{" + dev + "}T-RB", + loc, + cell, + element, + DEVICE_MAGNET, + UNIT_TEMP, + SIGTYPE_READBACK)); + return channels; + } + + private Collection insertValves( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String loc, + String cell) { + ArrayList channels = new ArrayList<>(); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "VA:", + "{" + "GV" + "}Opn-Sw", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "valve", + "position", + SIGTYPE_SWITCH)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "VA:", + "{" + "GV" + "}Opn-St", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "valve", + "position", + SIGTYPE_STATUS)); + return channels; + } + + private Collection insertGauges( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String dev, + String loc, + String cell) { + List channels = new ArrayList<>(); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "VA:", + "{" + dev + "}P-RB", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "gauge", + "pressure", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "VA:", + "{" + dev + OK_ST, + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "gauge", + "error", + SIGTYPE_STATUS)); + return channels; + } + + private Collection insertPumps( + Map> tokens, + AtomicInteger channelInCell, + String prefix, + String dev, + String loc, + String cell) { + List channels = new ArrayList<>(); + channels.addAll( + insertBunch( + tokens, + channelInCell, + 2, + prefix, + "VA:", + "{" + dev + "}I-RB", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "pump", + UNIT_CURRENT, + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + 2, + prefix, + "VA:", + "{" + dev + "}P-RB", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "pump", + "pressure", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + 2, + prefix, + "VA:", + "{" + dev + "}On-Sw", + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "pump", + UNIT_POWER, + SIGTYPE_SWITCH)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + 2, + prefix, + "VA:", + "{" + dev + OK_ST, + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "pump", + "error", + SIGTYPE_STATUS)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + 2, + prefix, + "VA:", + "{" + dev + ON_ST, + loc, + cell, + PopulateService.ELEMENT_VACUUM, + "pump", + UNIT_POWER, + SIGTYPE_STATUS)); + return channels; + } + + private Collection insertTemps( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String loc, + String cell) { + List channels = new ArrayList<>(); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PU:T", + "{" + "TC" + T_1_RB, + loc, + cell, + ELEMENT_TEMPERATURE_SENSOR, + DEVICE_SENSOR, + "temperature 1", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PU:T", + "{" + "TC" + T_2_RB, + loc, + cell, + ELEMENT_TEMPERATURE_SENSOR, + DEVICE_SENSOR, + "temperature 2", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PU:T", + "{" + "TC" + "}T:3-RB", + loc, + cell, + ELEMENT_TEMPERATURE_SENSOR, + DEVICE_SENSOR, + "temperature 3", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PU:T", + "{" + "TC" + "}T:4-RB", + loc, + cell, + ELEMENT_TEMPERATURE_SENSOR, + DEVICE_SENSOR, + "temperature 4", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "PU:T", + "{" + "TC" + ON_ST, + loc, + cell, + ELEMENT_TEMPERATURE_SENSOR, + DEVICE_SENSOR, + UNIT_POWER, + SIGTYPE_STATUS)); + return channels; + } + + private Collection insertBpms( + Map> tokens, + AtomicInteger channelInCell, + int count, + String prefix, + String dev, + String loc, + String cell, + String element) { + List channels = new ArrayList<>(); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "BI:", + "{" + dev + "}Pos:X-RB", + loc, + cell, + element, + "bpm", + "x position", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "BI:", + "{" + dev + "}Pos:Y-RB", + loc, + cell, + element, + "bpm", + "y position", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "BI:", + "{" + dev + "}Sig:X-RB", + loc, + cell, + element, + "bpm", + "x sigma", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "BI:", + "{" + dev + "}Sig:Y-RB", + loc, + cell, + element, + "bpm", + "y sigma", + SIGTYPE_READBACK)); + channels.addAll( + insertBunch( + tokens, + channelInCell, + count, + prefix, + "BI:", + "{" + dev + ON_ST, + loc, + cell, + element, + "bpm", + UNIT_POWER, + SIGTYPE_STATUS)); + return channels; + } + + private Collection insertBunch( + Map> tokens, + AtomicInteger channelInCellCounter, + int count, + String prefix, + String midfix, + String postfix, + String location, + String cell, + String element, + String device, + String unit, + String sigtype) { + int cw = count > 9 ? 2 : 1; + List result = new ArrayList<>(count); + for (int i = 1; i < count + 1; i++) { + Channel channel; + if (count == 1) { + channel = new Channel(prefix + cell + "-" + midfix + postfix, cowner); + } else { + channel = + new Channel( + prefix + cell + "-" + midfix + String.format("%0" + cw + "d", i) + postfix, cowner); + } + int channelInCell = channelInCellCounter.getAndIncrement(); + + channel.getProperties().add(new Property("location", powner, location)); + channel.getProperties().add(new Property("cell", powner, cell)); + channel.getProperties().add(new Property("element", powner, element)); + channel.getProperties().add(new Property("device", powner, device)); + if (count != 1) { + channel + .getProperties() + .add(new Property("family", powner, String.format("%0" + cw + "d", i))); + } + channel.getProperties().add(new Property("unit", powner, unit)); + channel.getProperties().add(new Property("type", powner, sigtype)); + + String posC = String.format("%03d", Math.round((10.0 / (count + 1)) * i)); + channel.getProperties().add(new Property("z_pos_r", powner, posC)); + + if (postfix.endsWith(T_1_RB)) { + channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "outside")); + } else if (postfix.endsWith(T_2_RB)) { + channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "inside")); + } else if (postfix.endsWith("}T:3-RB")) { + channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "top")); + } else if (postfix.endsWith("}T:4-RB")) { + channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "bottom")); + } else { + channel.getProperties().add(new Property(PROPERTY_NAME_MOUNT, powner, "center")); + } + + for (Entry> entry : tokens.entrySet()) { + // pop val from the tokens + int randIndex = ThreadLocalRandom.current().nextInt(entry.getValue().size()); + Integer val = entry.getValue().remove(randIndex); + channel + .getProperties() + .add(new Property("group" + entry.getKey(), powner, String.valueOf(val))); + channel.getTags().add(new Tag("group" + entry.getKey() + "_" + val, towner)); + } + + String group = GROUP + 6; + if (channelInCell % 2 == 1) { + channel.getProperties().add(new Property(group, powner, "500")); + channel.getTags().add(new Tag(group + "_500", towner)); + } else if (channelInCell < 2 * 200) { + channel.getProperties().add(new Property(group, powner, "200")); + channel.getTags().add(new Tag(group + "_200", towner)); + } else if (channelInCell < 2 * (200 + 100)) { + channel.getProperties().add(new Property(group, powner, "100")); + channel.getTags().add(new Tag(group + "_100", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50)) { + channel.getProperties().add(new Property(group, powner, "50")); + channel.getTags().add(new Tag(group + "_50", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50 + 20)) { + channel.getProperties().add(new Property(group, powner, "20")); + channel.getTags().add(new Tag(group + "_20", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10)) { + channel.getProperties().add(new Property(group, powner, "10")); + channel.getTags().add(new Tag(group + "_10", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5)) { + channel.getProperties().add(new Property(group, powner, "5")); + channel.getTags().add(new Tag(group + "_5", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2)) { + channel.getProperties().add(new Property(group, powner, "2")); + channel.getTags().add(new Tag(group + "_2", towner)); + } else if (channelInCell < 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { + channel.getProperties().add(new Property(group, powner, "1")); + channel.getTags().add(new Tag(group + "_1", towner)); + } else { + channel.getProperties().add(new Property(group, powner, "0")); + channel.getTags().add(new Tag(group + "_0", towner)); + } + + group = GROUP + 7; + if (channelInCell % 2 == 0) { + channel.getProperties().add(new Property(group, powner, String.valueOf(500))); + channel.getTags().add(new Tag(group + "_500", towner)); + } else if (channelInCell <= 2 * 200) { + channel.getProperties().add(new Property(group, powner, "200")); + channel.getTags().add(new Tag(group + "_200", towner)); + } else if (channelInCell <= 2 * (200 + 100)) { + channel.getProperties().add(new Property(group, powner, "100")); + channel.getTags().add(new Tag(group + "_100", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50)) { + channel.getProperties().add(new Property(group, powner, "50")); + channel.getTags().add(new Tag(group + "_50", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50 + 20)) { + channel.getProperties().add(new Property(group, powner, "20")); + channel.getTags().add(new Tag(group + "_20", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10)) { + channel.getProperties().add(new Property(group, powner, "10")); + channel.getTags().add(new Tag(group + "_10", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5)) { + channel.getProperties().add(new Property(group, powner, "5")); + channel.getTags().add(new Tag(group + "_5", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2)) { + channel.getProperties().add(new Property(group, powner, "2")); + channel.getTags().add(new Tag(group + "_2", towner)); + } else if (channelInCell <= 2 * (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { + channel.getProperties().add(new Property(group, powner, "1")); + channel.getTags().add(new Tag(group + "_1", towner)); + } else { + channel.getProperties().add(new Property(group, powner, "0")); + channel.getTags().add(new Tag(group + "_0", towner)); + } + + group = GROUP + 8; + if (channelInCell < 500) { + channel.getProperties().add(new Property(group, powner, String.valueOf(500))); + channel.getTags().add(new Tag(group + "_500", towner)); + } else if (channelInCell < 500 + 200) { + channel.getProperties().add(new Property(group, powner, "200")); + channel.getTags().add(new Tag(group + "_200", towner)); + } else if (channelInCell < 500 + (200 + 100)) { + channel.getProperties().add(new Property(group, powner, "100")); + channel.getTags().add(new Tag(group + "_100", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50)) { + channel.getProperties().add(new Property(group, powner, "50")); + channel.getTags().add(new Tag(group + "_50", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50 + 20)) { + channel.getProperties().add(new Property(group, powner, "20")); + channel.getTags().add(new Tag(group + "_20", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10)) { + channel.getProperties().add(new Property(group, powner, "10")); + channel.getTags().add(new Tag(group + "_10", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5)) { + channel.getProperties().add(new Property(group, powner, "5")); + channel.getTags().add(new Tag(group + "_5", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5 + 2)) { + channel.getProperties().add(new Property(group, powner, "2")); + channel.getTags().add(new Tag(group + "_2", towner)); + } else if (channelInCell < 500 + (200 + 100 + 50 + 20 + 10 + 5 + 2 + 1)) { + channel.getProperties().add(new Property(group, powner, "1")); + channel.getTags().add(new Tag(group + "_1", towner)); + } else { + channel.getProperties().add(new Property(group, powner, "0")); + channel.getTags().add(new Tag(group + "_0", towner)); + } + + group = GROUP + 9; + if (channelInCell >= 500) { + channel.getProperties().add(new Property(group, powner, String.valueOf(500))); + channel.getTags().add(new Tag(group + "_500", towner)); + } else if (channelInCell >= 500 - 200) { + channel.getProperties().add(new Property(group, powner, "200")); + channel.getTags().add(new Tag(group + "_200", towner)); + } else if (channelInCell >= 500 - 200 - 100) { + channel.getProperties().add(new Property(group, powner, "100")); + channel.getTags().add(new Tag(group + "_100", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50) { + channel.getProperties().add(new Property(group, powner, "50")); + channel.getTags().add(new Tag(group + "_50", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50 - 20) { + channel.getProperties().add(new Property(group, powner, "20")); + channel.getTags().add(new Tag(group + "_20", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10) { + channel.getProperties().add(new Property(group, powner, "10")); + channel.getTags().add(new Tag(group + "_10", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5) { + channel.getProperties().add(new Property(group, powner, "5")); + channel.getTags().add(new Tag(group + "_5", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5 - 2) { + channel.getProperties().add(new Property(group, powner, "2")); + channel.getTags().add(new Tag(group + "_2", towner)); + } else if (channelInCell >= 500 - 200 - 100 - 50 - 20 - 10 - 5 - 2 - 1) { + channel.getProperties().add(new Property(group, powner, "1")); + channel.getTags().add(new Tag(group + "_1", towner)); + } else { + channel.getProperties().add(new Property(group, powner, "0")); + channel.getTags().add(new Tag(group + "_0", towner)); + } + + for (int j = 20; j < maxProp; j++) { + channel + .getProperties() + .add( + new Property( + "prop" + String.format("%02d", j), + powner, + channelInCell + "-" + String.format("%02d", j))); + } + for (int k = 11; k < maxTag; k++) { + channel.getTags().add(new Tag("tag" + String.format("%02d", k), towner)); + } + int cellCount = Integer.parseInt(cell); + if (cellCount % 9 == 0) { + channel.getTags().add(new Tag("tagnine", towner)); + } else if (cellCount % 8 == 0) { + channel.getTags().add(new Tag("tageight", towner)); + } else if (cellCount % 7 == 0) { + channel.getTags().add(new Tag("tagseven", towner)); + } else if (cellCount % 6 == 0) { + channel.getTags().add(new Tag("tagsix", towner)); + } else if (cellCount % 5 == 0) { + channel.getTags().add(new Tag("tagfive", towner)); + } else if (cellCount % 4 == 0) { + channel.getTags().add(new Tag("tagfour", towner)); + } else if (cellCount % 3 == 0) { + channel.getTags().add(new Tag("tagthree", towner)); + } else if (cellCount % 2 == 0) { + channel.getTags().add(new Tag("tagtwo", towner)); + } else { + channel.getTags().add(new Tag("tagone", towner)); + } + + channelList.add(channel.getName()); + propertySet.addAll( + channel.getProperties().stream() + .map(p -> new Property(p.getName(), p.getOwner())) + .collect(Collectors.toSet())); + tagSet.addAll(channel.getTags()); + result.add(channel); } - + return result; + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessor.java b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessor.java index 677b9a41..7cf65142 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessor.java +++ b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessor.java @@ -1,16 +1,14 @@ package org.phoebus.channelfinder.processors; import com.fasterxml.jackson.core.JsonProcessingException; -import org.phoebus.channelfinder.entity.Channel; - import java.util.List; +import org.phoebus.channelfinder.entity.Channel; public interface ChannelProcessor { - boolean enabled(); - - String processorInfo(); + boolean enabled(); - long process(List channels) throws JsonProcessingException; + String processorInfo(); + long process(List channels) throws JsonProcessingException; } diff --git a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorManager.java b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorManager.java index 43907e51..35c7d800 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorManager.java +++ b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorManager.java @@ -1,12 +1,18 @@ package org.phoebus.channelfinder.processors; +import static org.phoebus.channelfinder.CFResourceDescriptors.CHANNEL_PROCESSOR_RESOURCE_URI; +import static org.phoebus.channelfinder.CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.phoebus.channelfinder.AuthorizationService; import org.phoebus.channelfinder.ChannelScroll; import org.phoebus.channelfinder.entity.Channel; @@ -25,136 +31,124 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static org.phoebus.channelfinder.CFResourceDescriptors.CHANNEL_PROCESSOR_RESOURCE_URI; -import static org.phoebus.channelfinder.CFResourceDescriptors.SEARCH_PARAM_DESCRIPTION; - @RestController @RequestMapping(CHANNEL_PROCESSOR_RESOURCE_URI) @EnableAutoConfiguration public class ChannelProcessorManager { - private static final Logger logger = Logger.getLogger(ChannelProcessorManager.class.getName()); + private static final Logger logger = Logger.getLogger(ChannelProcessorManager.class.getName()); - @Autowired - ChannelProcessorService channelProcessorService; - @Autowired - AuthorizationService authorizationService; + @Autowired ChannelProcessorService channelProcessorService; + @Autowired AuthorizationService authorizationService; - // TODO replace with PIT and search_after - @Autowired - ChannelScroll channelScroll; + // TODO replace with PIT and search_after + @Autowired ChannelScroll channelScroll; - @Value("${elasticsearch.query.size:10000}") - private int defaultMaxSize; + @Value("${elasticsearch.query.size:10000}") + private int defaultMaxSize; - @Operation( - summary = "Get processor count", - description = "Returns the number of channel processors.", - operationId = "getProcessorCount", - tags = {"ChannelProcessor"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Number of channel-processors", - content = @Content(schema = @Schema(implementation = Long.class))) - }) - @GetMapping("/count") - public long processorCount() { - return channelProcessorService.getProcessorCount(); - } + @Operation( + summary = "Get processor count", + description = "Returns the number of channel processors.", + operationId = "getProcessorCount", + tags = {"ChannelProcessor"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Number of channel-processors", + content = @Content(schema = @Schema(implementation = Long.class))) + }) + @GetMapping("/count") + public long processorCount() { + return channelProcessorService.getProcessorCount(); + } - @Operation( - summary = "Get processor info", - description = "Returns information about all channel processors.", - operationId = "getProcessorInfo", - tags = {"ChannelProcessor"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "List of processor-info", - content = @Content( - array = @ArraySchema (schema = @Schema(implementation = String.class)))) - }) - @GetMapping("/info") - public List processorInfo() { - return channelProcessorService.getProcessorsInfo(); - } + @Operation( + summary = "Get processor info", + description = "Returns information about all channel processors.", + operationId = "getProcessorInfo", + tags = {"ChannelProcessor"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "List of processor-info", + content = + @Content(array = @ArraySchema(schema = @Schema(implementation = String.class)))) + }) + @GetMapping("/info") + public List processorInfo() { + return channelProcessorService.getProcessorsInfo(); + } - @Operation( - summary = "Process all channels", - description = "Manually trigger processing on all channels in ChannelFinder.", - operationId = "processAllChannels", - tags = {"ChannelProcessor"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Number of channels where processor was called", - content = @Content(schema = @Schema(implementation = Long.class))), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) - }) - @PutMapping("/process/all") - public long processAllChannels() { - logger.log(Level.INFO, "Calling processor on ALL channels in ChannelFinder"); - // Only allow authorized users to trigger this operation - if(authorizationService - .isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), - AuthorizationService.ROLES.CF_ADMIN)) { - MultiValueMap searchParameters = new LinkedMultiValueMap(); - searchParameters.add("~name", "*"); - return processChannels(searchParameters); - } else { - logger.log(Level.SEVERE, - "User does not have the proper authorization to perform this operation: /process/all", - new ResponseStatusException(HttpStatus.UNAUTHORIZED)); - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, - "User does not have the proper authorization to perform this operation: /process/all"); - } + @Operation( + summary = "Process all channels", + description = "Manually trigger processing on all channels in ChannelFinder.", + operationId = "processAllChannels", + tags = {"ChannelProcessor"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Number of channels where processor was called", + content = @Content(schema = @Schema(implementation = Long.class))), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ResponseStatusException.class))) + }) + @PutMapping("/process/all") + public long processAllChannels() { + logger.log(Level.INFO, "Calling processor on ALL channels in ChannelFinder"); + // Only allow authorized users to trigger this operation + if (authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), + AuthorizationService.ROLES.CF_ADMIN)) { + MultiValueMap searchParameters = new LinkedMultiValueMap(); + searchParameters.add("~name", "*"); + return processChannels(searchParameters); + } else { + logger.log( + Level.SEVERE, + "User does not have the proper authorization to perform this operation: /process/all", + new ResponseStatusException(HttpStatus.UNAUTHORIZED)); + throw new ResponseStatusException( + HttpStatus.UNAUTHORIZED, + "User does not have the proper authorization to perform this operation: /process/all"); } + } - @Operation( - summary = "Process channels by query", - description = "Manually trigger processing on channels matching the given query.", - operationId = "processChannelsByQuery", - tags = {"ChannelProcessor"} - ) - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "Number of channels where processor was called", - content = @Content(schema = @Schema(implementation = Long.class))) - }) - @PutMapping("/process/query") - public long processChannels( - @Parameter(description = SEARCH_PARAM_DESCRIPTION) - @RequestParam MultiValueMap allRequestParams) { - long channelCount = 0; - Scroll scrollResult = channelScroll.query(allRequestParams); - channelCount += scrollResult.getChannels().size(); - processChannels(scrollResult.getChannels()); - while(scrollResult.getChannels().size() == defaultMaxSize) { - scrollResult = channelScroll.search(scrollResult.getId(), allRequestParams); - channelCount += scrollResult.getChannels().size(); - processChannels(scrollResult.getChannels()); - } - return channelCount; + @Operation( + summary = "Process channels by query", + description = "Manually trigger processing on channels matching the given query.", + operationId = "processChannelsByQuery", + tags = {"ChannelProcessor"}) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Number of channels where processor was called", + content = @Content(schema = @Schema(implementation = Long.class))) + }) + @PutMapping("/process/query") + public long processChannels( + @Parameter(description = SEARCH_PARAM_DESCRIPTION) @RequestParam + MultiValueMap allRequestParams) { + long channelCount = 0; + Scroll scrollResult = channelScroll.query(allRequestParams); + channelCount += scrollResult.getChannels().size(); + processChannels(scrollResult.getChannels()); + while (scrollResult.getChannels().size() == defaultMaxSize) { + scrollResult = channelScroll.search(scrollResult.getId(), allRequestParams); + channelCount += scrollResult.getChannels().size(); + processChannels(scrollResult.getChannels()); } + return channelCount; + } - @PutMapping("/process/channels") - public void processChannels(List channels) { - channelProcessorService.sendToProcessors(channels); - } + @PutMapping("/process/channels") + public void processChannels(List channels) { + channelProcessorService.sendToProcessors(channels); + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorService.java b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorService.java index b7a39bae..0f981798 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorService.java +++ b/src/main/java/org/phoebus/channelfinder/processors/ChannelProcessorService.java @@ -1,55 +1,63 @@ package org.phoebus.channelfinder.processors; -import org.phoebus.channelfinder.entity.Channel; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.task.TaskExecutor; -import org.springframework.stereotype.Service; - import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.phoebus.channelfinder.entity.Channel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.task.TaskExecutor; +import org.springframework.stereotype.Service; @Service public class ChannelProcessorService { - private static final Logger logger = Logger.getLogger(ChannelProcessorService.class.getName()); - - @Autowired - private List channelProcessors; - - @Autowired - private TaskExecutor taskExecutor; - - long getProcessorCount() { - return channelProcessors.size(); + private static final Logger logger = Logger.getLogger(ChannelProcessorService.class.getName()); + + @Autowired private List channelProcessors; + + @Autowired private TaskExecutor taskExecutor; + + long getProcessorCount() { + return channelProcessors.size(); + } + + List getProcessorsInfo() { + return channelProcessors.stream() + .map(ChannelProcessor::processorInfo) + .collect(Collectors.toList()); + } + + /** + * {@link ChannelProcessor} providers are called for the specified list of channels. Since a + * provider implementation may need some time to do it's job, calling them is done asynchronously. + * Any error handling or logging has to be done in the {@link ChannelProcessor}, but exceptions + * are handled here in order to not abort if any of the providers fails. + * + * @param channels list of channels to be processed + */ + public void sendToProcessors(List channels) { + logger.log( + Level.FINEST, () -> channels.stream().map(Channel::toLog).collect(Collectors.joining())); + if (channelProcessors.isEmpty()) { + return; } - - List getProcessorsInfo() { - return channelProcessors.stream().map(ChannelProcessor::processorInfo).collect(Collectors.toList()); - } - - /** - * {@link ChannelProcessor} providers are called for the specified list of channels. Since a provider - * implementation may need some time to do it's job, calling them is done asynchronously. Any - * error handling or logging has to be done in the {@link ChannelProcessor}, but exceptions are - * handled here in order to not abort if any of the providers fails. - * - * @param channels list of channels to be processed - */ - public void sendToProcessors(List channels) { - logger.log(Level.FINEST, () -> channels.stream().map(Channel::toLog).collect(Collectors.joining())); - if (channelProcessors.isEmpty()) { - return; - } - taskExecutor.execute(() -> channelProcessors.stream() + taskExecutor.execute( + () -> + channelProcessors.stream() .filter(ChannelProcessor::enabled) - .forEach(channelProcessor -> { - try { + .forEach( + channelProcessor -> { + try { channelProcessor.process(channels); - } catch (Exception e) { - logger.log(Level.WARNING, "ChannelProcessor " + channelProcessor.getClass().getName() + " throws exception", e); - } - })); - } + } catch (Exception e) { + logger.log( + Level.WARNING, + "ChannelProcessor " + + channelProcessor.getClass().getName() + + " throws exception", + e); + } + })); + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java b/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java index 49dc5ef8..a691f494 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java @@ -1,14 +1,6 @@ package org.phoebus.channelfinder.processors.aa; import com.fasterxml.jackson.core.JsonProcessingException; -import org.apache.commons.lang3.StringUtils; -import org.phoebus.channelfinder.entity.Channel; -import org.phoebus.channelfinder.entity.Property; -import org.phoebus.channelfinder.processors.ChannelProcessor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.beans.factory.annotation.Autowired; - import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; @@ -19,226 +11,261 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.phoebus.channelfinder.entity.Channel; +import org.phoebus.channelfinder.entity.Property; +import org.phoebus.channelfinder.processors.ChannelProcessor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; /** - * A post processor which uses the channel property *archive* to add pv's to the archiver appliance The archive - * parameters are specified in the property value, they consist of 2 parts the sampling method which can be scan or - * monitor the sampling rate defined in seconds - *

- * e.g. archive=monitor@1.0 + * A post processor which uses the channel property *archive* to add pv's to the archiver appliance + * The archive parameters are specified in the property value, they consist of 2 parts the sampling + * method which can be scan or monitor the sampling rate defined in seconds + * + *

e.g. archive=monitor@1.0 */ @Configuration public class AAChannelProcessor implements ChannelProcessor { - private static final Logger logger = Logger.getLogger(AAChannelProcessor.class.getName()); - - private static final String PV_STATUS_PROPERTY_NAME = "pvStatus"; // Matches in recsync - private static final String PV_STATUS_INACTIVE = "Inactive"; - public static final String PV_STATUS_ACTIVE = "Active"; - - - @Value("${aa.enabled:true}") - private boolean aaEnabled; - @Value("#{${aa.urls:{'default': 'http://localhost:17665'}}}") - private Map aaURLs; - @Value("${aa.default_alias:default}") - private List defaultArchivers; - @Value("${aa.pva:false}") - private boolean aaPVA; - @Value("${aa.archive_property_name:archive}") - private String archivePropertyName; - @Value("${aa.archiver_property_name:archiver}") - private String archiverPropertyName; - @Value("${aa.auto_pause:}") - private List autoPauseOptions; - - @Autowired - private final ArchiverClient archiverClient = new ArchiverClient(); - - @Override - public boolean enabled() { - return aaEnabled; + private static final Logger logger = Logger.getLogger(AAChannelProcessor.class.getName()); + + private static final String PV_STATUS_PROPERTY_NAME = "pvStatus"; // Matches in recsync + private static final String PV_STATUS_INACTIVE = "Inactive"; + public static final String PV_STATUS_ACTIVE = "Active"; + + @Value("${aa.enabled:true}") + private boolean aaEnabled; + + @Value("#{${aa.urls:{'default': 'http://localhost:17665'}}}") + private Map aaURLs; + + @Value("${aa.default_alias:default}") + private List defaultArchivers; + + @Value("${aa.pva:false}") + private boolean aaPVA; + + @Value("${aa.archive_property_name:archive}") + private String archivePropertyName; + + @Value("${aa.archiver_property_name:archiver}") + private String archiverPropertyName; + + @Value("${aa.auto_pause:}") + private List autoPauseOptions; + + @Autowired private final ArchiverClient archiverClient = new ArchiverClient(); + + @Override + public boolean enabled() { + return aaEnabled; + } + + @Override + public String processorInfo() { + Map processorProperties = + Map.of( + "archiveProperty", + archivePropertyName, + "archiverProperty", + archiverPropertyName, + "Archivers", + aaURLs.keySet().toString(), + "AutoPauseOn", + autoPauseOptions.toString()); + return "AAChannelProcessor: ProcessProperties " + processorProperties; + } + + /** + * Processes a list of channels through the archiver workflow. First the status of each pv is + * checked against the archiver. If the pv is not being archived and is not paused then the pv + * will be submitted to be archived. If the pvStatus auto pause is set, then the pv will be auto + * pause resumed as well. + * + * @param channels List of channels + * @return Return number of channels processed + * @throws JsonProcessingException If processing archiver responses fail. + */ + @Override + public long process(List channels) throws JsonProcessingException { + if (channels.isEmpty()) { + return 0; } - @Override - public String processorInfo() { - Map processorProperties = Map.of("archiveProperty", archivePropertyName, - "archiverProperty", archiverPropertyName, - "Archivers", aaURLs.keySet().toString(), - "AutoPauseOn", autoPauseOptions.toString() - ); - return "AAChannelProcessor: ProcessProperties " + processorProperties; + // Get Info (policy and version) of each archiver + Map archiversInfo = getArchiversInfo(aaURLs); + if (archiversInfo.isEmpty()) { + return 0; } - /** - * Processes a list of channels through the archiver workflow. - * First the status of each pv is checked against the archiver. - * If the pv is not being archived and is not paused then the pv will be submitted to be archived. - * If the pvStatus auto pause is set, then the pv will be auto pause resumed as well. - * - * @param channels List of channels - * @return Return number of channels processed - * @throws JsonProcessingException If processing archiver responses fail. - */ - @Override - public long process(List channels) throws JsonProcessingException { - if (channels.isEmpty()) { - return 0; - } - - // Get Info (policy and version) of each archiver - Map archiversInfo = getArchiversInfo(aaURLs); - if (archiversInfo.isEmpty()) { - return 0; - } - - Map> archiverAliasToArchivePVOptions = new HashMap<>(); // AA identifier, ArchivePVOptions - for (String alias : archiversInfo.keySet()) { - archiverAliasToArchivePVOptions.put(alias, new ArrayList<>()); - } - - logger.log(Level.INFO, "Get channelfinder properties for aa processor."); - channels.forEach(channel -> { - Optional archiveProperty = channel.getProperties().stream() - .filter(xmlProperty -> archivePropertyName.equalsIgnoreCase(xmlProperty.getName())) - .findFirst(); - if (archiveProperty.isPresent()) { - channel.getProperties().stream() - .filter(xmlProperty -> archiverPropertyName.equalsIgnoreCase(xmlProperty.getName())) - .findFirst() - .map(xmlProperty -> { - String archiverValue = xmlProperty.getValue(); - // archiver property can be comma separated list of archivers - if (archiverValue != null && !archiverValue.isEmpty()) { - return Arrays.stream(archiverValue.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()); - } else { - return defaultArchivers.stream(); - } - }) - .orElse(defaultArchivers.stream()) // Use defaultArchivers list if no matching property found - .forEach(archiverAlias -> { - try { - addChannelChange(channel, archiverAliasToArchivePVOptions, archiversInfo, archiveProperty, archiverAlias); - } catch (Exception e) { - logger.log(Level.WARNING, String.format("Failed to process %s", channel), e); - } - }); - } else if (autoPauseOptions.contains(archivePropertyName)) { - aaURLs.keySet().forEach(archiverAlias -> archiverAliasToArchivePVOptions - .get(archiverAlias) - .add(createArchivePV(List.of(), channel, "", PV_STATUS_INACTIVE))); - } - }); - long count = 0; - for (Map.Entry> e : archiverAliasToArchivePVOptions.entrySet()) { - ArchiverInfo archiverInfo = archiversInfo.get(e.getKey()); - if (archiverInfo == null) { - logger.log(Level.WARNING, String.format("Failed to process %s", e.getKey())); - continue; - } - Map archivePVSList = - e.getValue().stream().collect(Collectors.toMap(ArchivePVOptions::getPv, archivePVOptions -> archivePVOptions)); - Map> archiveActionArchivePVMap = - getArchiveActions(archivePVSList, archiverInfo); - count += archiverClient.configureAA(archiveActionArchivePVMap, archiverInfo.url()); - } - long finalCount = count; - logger.log(Level.INFO, () -> String.format("Configured %s channels.", finalCount)); - return finalCount; + Map> archiverAliasToArchivePVOptions = + new HashMap<>(); // AA identifier, ArchivePVOptions + for (String alias : archiversInfo.keySet()) { + archiverAliasToArchivePVOptions.put(alias, new ArrayList<>()); } - private void addChannelChange(Channel channel, - Map> aaArchivePVS, - Map archiversInfo, - Optional archiveProperty, String archiverAlias - ) { - String pvStatus = channel.getProperties().stream() - .filter(xmlProperty -> PV_STATUS_PROPERTY_NAME.equalsIgnoreCase(xmlProperty.getName())) + logger.log(Level.INFO, "Get channelfinder properties for aa processor."); + channels.forEach( + channel -> { + Optional archiveProperty = + channel.getProperties().stream() + .filter( + xmlProperty -> archivePropertyName.equalsIgnoreCase(xmlProperty.getName())) + .findFirst(); + if (archiveProperty.isPresent()) { + channel.getProperties().stream() + .filter(xmlProperty -> archiverPropertyName.equalsIgnoreCase(xmlProperty.getName())) .findFirst() - .map(Property::getValue) - .orElse(PV_STATUS_INACTIVE); - if (aaArchivePVS.containsKey(archiverAlias) && archiveProperty.isPresent()) { - ArchivePVOptions newArchiverPV = createArchivePV( - archiversInfo.get(archiverAlias).policies(), - channel, - archiveProperty.get().getValue(), - autoPauseOptions.contains(PV_STATUS_PROPERTY_NAME) ? pvStatus : PV_STATUS_ACTIVE); - aaArchivePVS.get(archiverAlias).add(newArchiverPV); - } + .map( + xmlProperty -> { + String archiverValue = xmlProperty.getValue(); + // archiver property can be comma separated list of archivers + if (archiverValue != null && !archiverValue.isEmpty()) { + return Arrays.stream(archiverValue.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()); + } else { + return defaultArchivers.stream(); + } + }) + .orElse( + defaultArchivers + .stream()) // Use defaultArchivers list if no matching property found + .forEach( + archiverAlias -> { + try { + addChannelChange( + channel, + archiverAliasToArchivePVOptions, + archiversInfo, + archiveProperty, + archiverAlias); + } catch (Exception e) { + logger.log( + Level.WARNING, String.format("Failed to process %s", channel), e); + } + }); + } else if (autoPauseOptions.contains(archivePropertyName)) { + aaURLs + .keySet() + .forEach( + archiverAlias -> + archiverAliasToArchivePVOptions + .get(archiverAlias) + .add(createArchivePV(List.of(), channel, "", PV_STATUS_INACTIVE))); + } + }); + long count = 0; + for (Map.Entry> e : archiverAliasToArchivePVOptions.entrySet()) { + ArchiverInfo archiverInfo = archiversInfo.get(e.getKey()); + if (archiverInfo == null) { + logger.log(Level.WARNING, String.format("Failed to process %s", e.getKey())); + continue; + } + Map archivePVSList = + e.getValue().stream() + .collect( + Collectors.toMap(ArchivePVOptions::getPv, archivePVOptions -> archivePVOptions)); + Map> archiveActionArchivePVMap = + getArchiveActions(archivePVSList, archiverInfo); + count += archiverClient.configureAA(archiveActionArchivePVMap, archiverInfo.url()); } + long finalCount = count; + logger.log(Level.INFO, () -> String.format("Configured %s channels.", finalCount)); + return finalCount; + } - private ArchiveAction pickArchiveAction(String archiveStatus, String pvStatus) { - if (archiveStatus.equals("Being archived") && (pvStatus.equals(PV_STATUS_INACTIVE))) { - return ArchiveAction.PAUSE; - } else if (archiveStatus.equals("Paused") && (pvStatus.equals(PV_STATUS_ACTIVE))) { - return ArchiveAction.RESUME; - } else if (!archiveStatus.equals("Being archived") - && !archiveStatus.equals("Paused") - && pvStatus.equals(PV_STATUS_ACTIVE)) { // If archive status anything else - return ArchiveAction.ARCHIVE; - } - - return ArchiveAction.NONE; + private void addChannelChange( + Channel channel, + Map> aaArchivePVS, + Map archiversInfo, + Optional archiveProperty, + String archiverAlias) { + String pvStatus = + channel.getProperties().stream() + .filter(xmlProperty -> PV_STATUS_PROPERTY_NAME.equalsIgnoreCase(xmlProperty.getName())) + .findFirst() + .map(Property::getValue) + .orElse(PV_STATUS_INACTIVE); + if (aaArchivePVS.containsKey(archiverAlias) && archiveProperty.isPresent()) { + ArchivePVOptions newArchiverPV = + createArchivePV( + archiversInfo.get(archiverAlias).policies(), + channel, + archiveProperty.get().getValue(), + autoPauseOptions.contains(PV_STATUS_PROPERTY_NAME) ? pvStatus : PV_STATUS_ACTIVE); + aaArchivePVS.get(archiverAlias).add(newArchiverPV); } + } - private Map> getArchiveActions( - Map archivePVS, ArchiverInfo archiverInfo) { - if (archiverInfo == null) { - return Map.of(); - } - - logger.log(Level.INFO, () -> String.format("Get archiver status in archiver %s", archiverInfo)); - - Map> result = new EnumMap<>(ArchiveAction.class); - Arrays.stream(ArchiveAction.values()).forEach(archiveAction -> result.put(archiveAction, new ArrayList<>())); - // Don't request to archive an empty list. - if (archivePVS.isEmpty()) { - return result; - } - List> statuses = archiverClient.getStatuses(archivePVS, archiverInfo.url(), archiverInfo.alias()); - statuses - .forEach(archivePVStatusJsonMap -> { - String archiveStatus = archivePVStatusJsonMap.get("status"); - String pvName = archivePVStatusJsonMap.get("pvName"); - String pvStatus = archivePVS.get(pvName).getPvStatus(); - ArchiveAction action = pickArchiveAction(archiveStatus, pvStatus); - result.get(action).add(archivePVS.get(pvName)); - }); - return result; + private ArchiveAction pickArchiveAction(String archiveStatus, String pvStatus) { + if (archiveStatus.equals("Being archived") && (pvStatus.equals(PV_STATUS_INACTIVE))) { + return ArchiveAction.PAUSE; + } else if (archiveStatus.equals("Paused") && (pvStatus.equals(PV_STATUS_ACTIVE))) { + return ArchiveAction.RESUME; + } else if (!archiveStatus.equals("Being archived") + && !archiveStatus.equals("Paused") + && pvStatus.equals(PV_STATUS_ACTIVE)) { // If archive status anything else + return ArchiveAction.ARCHIVE; } - private ArchivePVOptions createArchivePV( - List policyList, Channel channel, String archiveProperty, String pvStaus) { - ArchivePVOptions newArchiverPV = new ArchivePVOptions(); - if (aaPVA && !channel.getName().contains("://")) { - newArchiverPV.setPv("pva://" + channel.getName()); - } else { - newArchiverPV.setPv(channel.getName()); - } - newArchiverPV.setSamplingParameters(archiveProperty, policyList); - newArchiverPV.setPvStatus(pvStaus); - return newArchiverPV; + return ArchiveAction.NONE; + } + + private Map> getArchiveActions( + Map archivePVS, ArchiverInfo archiverInfo) { + if (archiverInfo == null) { + return Map.of(); } + logger.log(Level.INFO, () -> String.format("Get archiver status in archiver %s", archiverInfo)); - private Map getArchiversInfo(Map aaURLs) { - Map result = new HashMap<>(); - for (Map.Entry aa : aaURLs.entrySet()) { - if (StringUtils.isEmpty(aa.getValue())) { - // Empty archiver tagged - continue; - } - String version = archiverClient.getVersion(aa.getValue()); - List policies = archiverClient.getAAPolicies(aa.getValue()); - result.put( - aa.getKey(), - new ArchiverInfo(aa.getKey(), aa.getValue(), version, policies) - ); - } - return result; + Map> result = new EnumMap<>(ArchiveAction.class); + Arrays.stream(ArchiveAction.values()) + .forEach(archiveAction -> result.put(archiveAction, new ArrayList<>())); + // Don't request to archive an empty list. + if (archivePVS.isEmpty()) { + return result; } + List> statuses = + archiverClient.getStatuses(archivePVS, archiverInfo.url(), archiverInfo.alias()); + statuses.forEach( + archivePVStatusJsonMap -> { + String archiveStatus = archivePVStatusJsonMap.get("status"); + String pvName = archivePVStatusJsonMap.get("pvName"); + String pvStatus = archivePVS.get(pvName).getPvStatus(); + ArchiveAction action = pickArchiveAction(archiveStatus, pvStatus); + result.get(action).add(archivePVS.get(pvName)); + }); + return result; + } + private ArchivePVOptions createArchivePV( + List policyList, Channel channel, String archiveProperty, String pvStaus) { + ArchivePVOptions newArchiverPV = new ArchivePVOptions(); + if (aaPVA && !channel.getName().contains("://")) { + newArchiverPV.setPv("pva://" + channel.getName()); + } else { + newArchiverPV.setPv(channel.getName()); + } + newArchiverPV.setSamplingParameters(archiveProperty, policyList); + newArchiverPV.setPvStatus(pvStaus); + return newArchiverPV; + } + private Map getArchiversInfo(Map aaURLs) { + Map result = new HashMap<>(); + for (Map.Entry aa : aaURLs.entrySet()) { + if (StringUtils.isEmpty(aa.getValue())) { + // Empty archiver tagged + continue; + } + String version = archiverClient.getVersion(aa.getValue()); + List policies = archiverClient.getAAPolicies(aa.getValue()); + result.put(aa.getKey(), new ArchiverInfo(aa.getKey(), aa.getValue(), version, policies)); + } + return result; + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiveAction.java b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiveAction.java index 150277fa..d44545b1 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiveAction.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiveAction.java @@ -1,18 +1,18 @@ package org.phoebus.channelfinder.processors.aa; public enum ArchiveAction { - ARCHIVE("/archivePV"), - PAUSE("/pauseArchivingPV"), - RESUME("/resumeArchivingPV"), - NONE(""); + ARCHIVE("/archivePV"), + PAUSE("/pauseArchivingPV"), + RESUME("/resumeArchivingPV"), + NONE(""); - private final String endpoint; + private final String endpoint; - ArchiveAction(final String endpoint) { - this.endpoint = endpoint; - } + ArchiveAction(final String endpoint) { + this.endpoint = endpoint; + } - public String getEndpoint() { - return this.endpoint; - } + public String getEndpoint() { + return this.endpoint; + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchivePVOptions.java b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchivePVOptions.java index 8b99906a..b483a12f 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchivePVOptions.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchivePVOptions.java @@ -3,112 +3,124 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @JsonInclude(JsonInclude.Include.NON_NULL) public class ArchivePVOptions { - private static final Logger logger = Logger.getLogger(ArchivePVOptions.class.getName()); - - private String pv; - @JsonProperty("samplingmethod") - private String samplingMethod; - @JsonProperty("samplingperiod") - private String samplingPeriod; - private String policy; - @JsonIgnore - private String pvStatus; - - @Override - public String toString() { - return "ArchivePV{" + "pv='" - + pv + '\'' + ", samplingMethod='" - + samplingMethod + '\'' + ", samplingPeriod='" - + samplingPeriod + '\'' + ", policy='" - + policy + '\'' + ", pvStatus='" - + pvStatus + '\'' + '}'; + private static final Logger logger = Logger.getLogger(ArchivePVOptions.class.getName()); + + private String pv; + + @JsonProperty("samplingmethod") + private String samplingMethod; + + @JsonProperty("samplingperiod") + private String samplingPeriod; + + private String policy; + @JsonIgnore private String pvStatus; + + @Override + public String toString() { + return "ArchivePV{" + + "pv='" + + pv + + '\'' + + ", samplingMethod='" + + samplingMethod + + '\'' + + ", samplingPeriod='" + + samplingPeriod + + '\'' + + ", policy='" + + policy + + '\'' + + ", pvStatus='" + + pvStatus + + '\'' + + '}'; + } + + public String getPv() { + return pv; + } + + public void setPv(String pv) { + this.pv = pv; + } + + /** + * process the archive property value string to configure the sampling method and rate + * + * @param parameters string expected in the form monitor@1.0 + */ + public void setSamplingParameters(String parameters, List policyList) { + if (parameters.equalsIgnoreCase("default")) { + return; } - - public String getPv() { - return pv; + if (policyList.contains(parameters)) { + setPolicy(parameters); + return; } - - public void setPv(String pv) { - this.pv = pv; + String[] p = parameters.split("@"); + if (p.length == 2) { + switch (p[0].toUpperCase()) { + case "MONITOR": + setSamplingMethod("MONITOR"); + break; + case "SCAN": + setSamplingMethod("SCAN"); + break; + default: + // invalid sampling method + logger.log(Level.WARNING, "Invalid sampling method " + p[0]); + return; + } + // ignore anything after first space + String sp = p[1].split("\\s")[0]; + // catch number format errors + try { + Float.parseFloat(sp); + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid sampling period" + sp); + setSamplingMethod(null); + return; + } + setSamplingPeriod(sp); } + } - /** - * process the archive property value string to configure the sampling method and rate - * - * @param parameters string expected in the form monitor@1.0 - */ - public void setSamplingParameters(String parameters, List policyList) { - if (parameters.equalsIgnoreCase("default")) { - return; - } - if (policyList.contains(parameters)) { - setPolicy(parameters); - return; - } - String[] p = parameters.split("@"); - if (p.length == 2) { - switch (p[0].toUpperCase()) { - case "MONITOR": - setSamplingMethod("MONITOR"); - break; - case "SCAN": - setSamplingMethod("SCAN"); - break; - default: - // invalid sampling method - logger.log(Level.WARNING, "Invalid sampling method " + p[0]); - return; - } - // ignore anything after first space - String sp = p[1].split("\\s")[0]; - // catch number format errors - try { - Float.parseFloat(sp); - } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Invalid sampling period" + sp); - setSamplingMethod(null); - return; - } - setSamplingPeriod(sp); - } - } + public String getSamplingMethod() { + return samplingMethod; + } - public String getSamplingMethod() { - return samplingMethod; - } + public void setSamplingMethod(String samplingMethod) { + this.samplingMethod = samplingMethod; + } - public void setSamplingMethod(String samplingMethod) { - this.samplingMethod = samplingMethod; - } + public String getSamplingPeriod() { + return samplingPeriod; + } - public String getSamplingPeriod() { - return samplingPeriod; - } + public void setSamplingPeriod(String samplingPeriod) { + this.samplingPeriod = samplingPeriod; + } - public void setSamplingPeriod(String samplingPeriod) { - this.samplingPeriod = samplingPeriod; - } - - public String getPolicy() { - return policy; - } + public String getPolicy() { + return policy; + } - public void setPolicy(String policy) { - this.policy = policy; - } + public void setPolicy(String policy) { + this.policy = policy; + } - public String getPvStatus() { - return pvStatus; - } + public String getPvStatus() { + return pvStatus; + } - public void setPvStatus(String pvStatus) { - this.pvStatus = pvStatus; - } + public void setPvStatus(String pvStatus) { + this.pvStatus = pvStatus; + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java index da4ebd68..ee7edd65 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java @@ -3,14 +3,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.lang3.StringUtils; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.beans.factory.annotation.Value; -import reactor.core.publisher.Mono; - import java.net.URI; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -23,218 +15,253 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; @Component public class ArchiverClient { - private static final Logger logger = Logger.getLogger(ArchiverClient.class.getName()); - private static final int STATUS_BATCH_SIZE = 100; // Limit comes from tomcat server maxHttpHeaderSize which by default is a header of size 8k - - private final WebClient client = WebClient.create(); - - private static final String MGMT_RESOURCE = "/mgmt/bpl"; - private static final String POLICY_RESOURCE = MGMT_RESOURCE + "/getPolicyList"; - private static final String PV_STATUS_RESOURCE = MGMT_RESOURCE + "/getPVStatus"; - private static final String ARCHIVER_VERSIONS_RESOURCE = MGMT_RESOURCE + "/getVersions"; - private static final ObjectMapper objectMapper = new ObjectMapper(); - - @Value("${aa.timeout_seconds:15}") - private int timeoutSeconds; - @Value("${aa.post_support:}") - private List postSupportArchivers; - - private Stream> partitionSet(Set pvSet, int pageSize) { - List list = new ArrayList<>(pvSet); - return IntStream.range(0, (list.size() + pageSize - 1) / pageSize) - .mapToObj(i -> list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size()))); - } + private static final Logger logger = Logger.getLogger(ArchiverClient.class.getName()); + private static final int STATUS_BATCH_SIZE = + 100; // Limit comes from tomcat server maxHttpHeaderSize which by default is a header of size + // 8k - List> getStatuses(Map archivePVS, String archiverURL, String archiverAlias) { - Set pvs = archivePVS.keySet(); - Boolean postSupportOverride = postSupportArchivers.contains(archiverAlias); - logger.log(Level.INFO, "Archiver Alias: {0}", archiverAlias); - logger.log(Level.INFO, "Post Support Override Archivers: {0}", postSupportArchivers); - - if (Boolean.TRUE.equals(postSupportOverride)) { - logger.log(Level.INFO, "Post Support"); - return getStatusesFromPvListBody(archiverURL, pvs.stream().toList()); - } else { - logger.log(Level.INFO, "Query Support"); - Stream> stream = partitionSet(pvs, STATUS_BATCH_SIZE); - - return stream.map(pvList -> getStatusesFromPvListQuery(archiverURL, pvList)).flatMap(List::stream).toList(); - } - } + private final WebClient client = WebClient.create(); - private List> getStatusesFromPvListQuery(String archiverURL, List pvs) { - String uriString = archiverURL + PV_STATUS_RESOURCE; - URI pvStatusURI = UriComponentsBuilder.fromUri(URI.create(uriString)) - .queryParam("pv", String.join(",", pvs)) - .build() - .toUri(); - - String response = client.get() - .uri(pvStatusURI) - .retrieve() - .bodyToMono(String.class) - .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) - .onErrorResume(e -> showError(uriString, e)) - .block(); - - try { - return objectMapper - .readValue(response, new TypeReference<>() { - }); - } catch (JsonProcessingException e) { - logger.log(Level.WARNING, "Could not parse pv status response: " + e.getMessage()); - } catch (Exception e) { - logger.log(Level.WARNING, String.format("Error when trying to get status from pv list query: %s", e.getMessage())); - } - return List.of(); + private static final String MGMT_RESOURCE = "/mgmt/bpl"; + private static final String POLICY_RESOURCE = MGMT_RESOURCE + "/getPolicyList"; + private static final String PV_STATUS_RESOURCE = MGMT_RESOURCE + "/getPVStatus"; + private static final String ARCHIVER_VERSIONS_RESOURCE = MGMT_RESOURCE + "/getVersions"; + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @Value("${aa.timeout_seconds:15}") + private int timeoutSeconds; + + @Value("${aa.post_support:}") + private List postSupportArchivers; + + private Stream> partitionSet(Set pvSet, int pageSize) { + List list = new ArrayList<>(pvSet); + return IntStream.range(0, (list.size() + pageSize - 1) / pageSize) + .mapToObj(i -> list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size()))); + } + + List> getStatuses( + Map archivePVS, String archiverURL, String archiverAlias) { + Set pvs = archivePVS.keySet(); + Boolean postSupportOverride = postSupportArchivers.contains(archiverAlias); + logger.log(Level.INFO, "Archiver Alias: {0}", archiverAlias); + logger.log(Level.INFO, "Post Support Override Archivers: {0}", postSupportArchivers); + + if (Boolean.TRUE.equals(postSupportOverride)) { + logger.log(Level.INFO, "Post Support"); + return getStatusesFromPvListBody(archiverURL, pvs.stream().toList()); + } else { + logger.log(Level.INFO, "Query Support"); + Stream> stream = partitionSet(pvs, STATUS_BATCH_SIZE); + + return stream + .map(pvList -> getStatusesFromPvListQuery(archiverURL, pvList)) + .flatMap(List::stream) + .toList(); } + } + + private List> getStatusesFromPvListQuery( + String archiverURL, List pvs) { + String uriString = archiverURL + PV_STATUS_RESOURCE; + URI pvStatusURI = + UriComponentsBuilder.fromUri(URI.create(uriString)) + .queryParam("pv", String.join(",", pvs)) + .build() + .toUri(); + + String response = + client + .get() + .uri(pvStatusURI) + .retrieve() + .bodyToMono(String.class) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) + .onErrorResume(e -> showError(uriString, e)) + .block(); - private List> getStatusesFromPvListBody(String archiverURL, List pvs) { - String uriString = archiverURL + PV_STATUS_RESOURCE; - String response = client.post() - .uri(URI.create(uriString)) - .contentType(MediaType.APPLICATION_JSON) - .bodyValue(pvs) - .retrieve() - .bodyToMono(String.class) - .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) - .onErrorResume(e -> showError(uriString, e)) - .block(); - - // Structure of response is - // [{"pvName":"PV:1", "status":"Paused", ... }, {"pvName": "PV:2"}, {"status": "Being archived"}, ...}, ... - // ] - - try { - return objectMapper - .readValue(response, new TypeReference<>() { - }); - } catch (JsonProcessingException e) { - logger.log(Level.WARNING, "Could not parse pv status response: " + e.getMessage()); - } catch (Exception e) { - logger.log(Level.WARNING, String.format("Error when trying to get status from pv list body: %s", e.getMessage())); - } - return List.of(); + try { + return objectMapper.readValue(response, new TypeReference<>() {}); + } catch (JsonProcessingException e) { + logger.log(Level.WARNING, "Could not parse pv status response: " + e.getMessage()); + } catch (Exception e) { + logger.log( + Level.WARNING, + String.format("Error when trying to get status from pv list query: %s", e.getMessage())); } + return List.of(); + } - private void submitAction(String values, String endpoint, String aaURL) { - String uriString = aaURL + MGMT_RESOURCE + endpoint; - try { - String response = client.post() - .uri(URI.create(uriString)) - .contentType(MediaType.APPLICATION_JSON) - .bodyValue(values) - .retrieve() - .bodyToMono(String.class) - .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) - .onErrorResume(e -> showError(uriString, e)) - .block(); - logger.log(Level.FINE, () -> response); - - } catch (Exception e) { - logger.log(Level.WARNING, String.format("Failed to submit %s to %s on %s", values, endpoint, aaURL), e); - } + private List> getStatusesFromPvListBody( + String archiverURL, List pvs) { + String uriString = archiverURL + PV_STATUS_RESOURCE; + String response = + client + .post() + .uri(URI.create(uriString)) + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(pvs) + .retrieve() + .bodyToMono(String.class) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) + .onErrorResume(e -> showError(uriString, e)) + .block(); + + // Structure of response is + // [{"pvName":"PV:1", "status":"Paused", ... }, {"pvName": "PV:2"}, {"status": "Being + // archived"}, ...}, ... + // ] + + try { + return objectMapper.readValue(response, new TypeReference<>() {}); + } catch (JsonProcessingException e) { + logger.log(Level.WARNING, "Could not parse pv status response: " + e.getMessage()); + } catch (Exception e) { + logger.log( + Level.WARNING, + String.format("Error when trying to get status from pv list body: %s", e.getMessage())); } + return List.of(); + } + private void submitAction(String values, String endpoint, String aaURL) { + String uriString = aaURL + MGMT_RESOURCE + endpoint; + try { + String response = + client + .post() + .uri(URI.create(uriString)) + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(values) + .retrieve() + .bodyToMono(String.class) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) + .onErrorResume(e -> showError(uriString, e)) + .block(); + logger.log(Level.FINE, () -> response); - long configureAA(Map> archivePVS, String aaURL) - throws JsonProcessingException { - logger.log(Level.INFO, () -> String.format("Configure PVs %s in %s", archivePVS.toString(), aaURL)); - long count = 0; - // Don't request to archive an empty list. - if (archivePVS.isEmpty()) { - return count; - } - if (!archivePVS.get(ArchiveAction.ARCHIVE).isEmpty()) { - logger.log( - Level.INFO, - () -> "Submitting to be archived " - + archivePVS.get(ArchiveAction.ARCHIVE).size() + " pvs"); - submitAction( - objectMapper.writeValueAsString(archivePVS.get(ArchiveAction.ARCHIVE)), - ArchiveAction.ARCHIVE.getEndpoint(), - aaURL); - count += archivePVS.get(ArchiveAction.ARCHIVE).size(); - } - if (!archivePVS.get(ArchiveAction.PAUSE).isEmpty()) { - logger.log( - Level.INFO, - () -> "Submitting to be paused " - + archivePVS.get(ArchiveAction.PAUSE).size() + " pvs"); - submitAction( - objectMapper.writeValueAsString(archivePVS.get(ArchiveAction.PAUSE).stream() - .map(ArchivePVOptions::getPv) - .collect(Collectors.toList())), - ArchiveAction.PAUSE.getEndpoint(), - aaURL); - count += archivePVS.get(ArchiveAction.PAUSE).size(); - } - if (!archivePVS.get(ArchiveAction.RESUME).isEmpty()) { - logger.log( - Level.INFO, - () -> "Submitting to be resumed " - + archivePVS.get(ArchiveAction.RESUME).size() + " pvs"); - submitAction( - objectMapper.writeValueAsString(archivePVS.get(ArchiveAction.RESUME).stream() - .map(ArchivePVOptions::getPv) - .collect(Collectors.toList())), - ArchiveAction.RESUME.getEndpoint(), - aaURL); - count += archivePVS.get(ArchiveAction.RESUME).size(); - } - return count; + } catch (Exception e) { + logger.log( + Level.WARNING, + String.format("Failed to submit %s to %s on %s", values, endpoint, aaURL), + e); } + } - List getAAPolicies(String aaURL) { - if (StringUtils.isEmpty(aaURL)) { - return List.of(); - } - try { - String uriString = aaURL + POLICY_RESOURCE; - String response = client.get() - .uri(URI.create(uriString)) - .retrieve() - .bodyToMono(String.class) - .timeout(Duration.of(10, ChronoUnit.SECONDS)) - .onErrorResume(e -> showError(uriString, e)) - .block(); - Map policyMap = objectMapper.readValue(response, Map.class); - return new ArrayList<>(policyMap.keySet()); - } catch (Exception e) { - // problem collecting policies from AA, so warn and return empty list - logger.log(Level.WARNING, "Could not get AA policies list from: " + aaURL, e); - return List.of(); - } + long configureAA(Map> archivePVS, String aaURL) + throws JsonProcessingException { + logger.log( + Level.INFO, () -> String.format("Configure PVs %s in %s", archivePVS.toString(), aaURL)); + long count = 0; + // Don't request to archive an empty list. + if (archivePVS.isEmpty()) { + return count; + } + if (!archivePVS.get(ArchiveAction.ARCHIVE).isEmpty()) { + logger.log( + Level.INFO, + () -> + "Submitting to be archived " + archivePVS.get(ArchiveAction.ARCHIVE).size() + " pvs"); + submitAction( + objectMapper.writeValueAsString(archivePVS.get(ArchiveAction.ARCHIVE)), + ArchiveAction.ARCHIVE.getEndpoint(), + aaURL); + count += archivePVS.get(ArchiveAction.ARCHIVE).size(); + } + if (!archivePVS.get(ArchiveAction.PAUSE).isEmpty()) { + logger.log( + Level.INFO, + () -> "Submitting to be paused " + archivePVS.get(ArchiveAction.PAUSE).size() + " pvs"); + submitAction( + objectMapper.writeValueAsString( + archivePVS.get(ArchiveAction.PAUSE).stream() + .map(ArchivePVOptions::getPv) + .collect(Collectors.toList())), + ArchiveAction.PAUSE.getEndpoint(), + aaURL); + count += archivePVS.get(ArchiveAction.PAUSE).size(); } + if (!archivePVS.get(ArchiveAction.RESUME).isEmpty()) { + logger.log( + Level.INFO, + () -> "Submitting to be resumed " + archivePVS.get(ArchiveAction.RESUME).size() + " pvs"); + submitAction( + objectMapper.writeValueAsString( + archivePVS.get(ArchiveAction.RESUME).stream() + .map(ArchivePVOptions::getPv) + .collect(Collectors.toList())), + ArchiveAction.RESUME.getEndpoint(), + aaURL); + count += archivePVS.get(ArchiveAction.RESUME).size(); + } + return count; + } - String getVersion(String archiverURL) { - try { - String uriString = archiverURL + ARCHIVER_VERSIONS_RESOURCE; - String response = client.get() - .uri(URI.create(uriString)) - .retrieve() - .bodyToMono(String.class) - .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) - .onErrorResume(e -> showError(uriString, e)) - .block(); - Map versionMap = objectMapper.readValue(response, Map.class); - String[] mgmtVersion = versionMap.get("mgmt_version").split("Archiver Appliance Version "); - if (mgmtVersion.length > 1) { - return mgmtVersion[1]; - } - - } catch (Exception e) { - logger.log(Level.WARNING, "Could not get version from: " + archiverURL, e); - return ""; - } - return ""; + List getAAPolicies(String aaURL) { + if (StringUtils.isEmpty(aaURL)) { + return List.of(); + } + try { + String uriString = aaURL + POLICY_RESOURCE; + String response = + client + .get() + .uri(URI.create(uriString)) + .retrieve() + .bodyToMono(String.class) + .timeout(Duration.of(10, ChronoUnit.SECONDS)) + .onErrorResume(e -> showError(uriString, e)) + .block(); + Map policyMap = objectMapper.readValue(response, Map.class); + return new ArrayList<>(policyMap.keySet()); + } catch (Exception e) { + // problem collecting policies from AA, so warn and return empty list + logger.log(Level.WARNING, "Could not get AA policies list from: " + aaURL, e); + return List.of(); } + } - private Mono showError(String uriString, Throwable error) { - logger.log(Level.WARNING, String.format("There was an error getting a response with URI: %s. Error: %s", uriString, error.getMessage())); - return Mono.empty(); + String getVersion(String archiverURL) { + try { + String uriString = archiverURL + ARCHIVER_VERSIONS_RESOURCE; + String response = + client + .get() + .uri(URI.create(uriString)) + .retrieve() + .bodyToMono(String.class) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) + .onErrorResume(e -> showError(uriString, e)) + .block(); + Map versionMap = objectMapper.readValue(response, Map.class); + String[] mgmtVersion = versionMap.get("mgmt_version").split("Archiver Appliance Version "); + if (mgmtVersion.length > 1) { + return mgmtVersion[1]; + } + + } catch (Exception e) { + logger.log(Level.WARNING, "Could not get version from: " + archiverURL, e); + return ""; } + return ""; + } + + private Mono showError(String uriString, Throwable error) { + logger.log( + Level.WARNING, + String.format( + "There was an error getting a response with URI: %s. Error: %s", + uriString, error.getMessage())); + return Mono.empty(); + } } diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverInfo.java b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverInfo.java index 0f971abf..31219b53 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverInfo.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverInfo.java @@ -2,5 +2,4 @@ import java.util.List; -public record ArchiverInfo(String alias, String url, String version, List policies) { -} +public record ArchiverInfo(String alias, String url, String version, List policies) {} diff --git a/src/test/java/org/junit/rules/ExternalResource.java b/src/test/java/org/junit/rules/ExternalResource.java index 23c222b1..95788f48 100644 --- a/src/test/java/org/junit/rules/ExternalResource.java +++ b/src/test/java/org/junit/rules/ExternalResource.java @@ -1,11 +1,8 @@ - package org.junit.rules; /** - * "Fake" class used as a replacement for Junit4-dependent classes. - * See more at: - * GenericContainer run from Jupiter tests shouldn't require JUnit 4.x library on runtime classpath - * . + * "Fake" class used as a replacement for Junit4-dependent classes. See more at: GenericContainer run from + * Jupiter tests shouldn't require JUnit 4.x library on runtime classpath . */ -public class ExternalResource { -} \ No newline at end of file +public class ExternalResource {} diff --git a/src/test/java/org/junit/rules/TestRule.java b/src/test/java/org/junit/rules/TestRule.java index c27ad265..34be5cd6 100644 --- a/src/test/java/org/junit/rules/TestRule.java +++ b/src/test/java/org/junit/rules/TestRule.java @@ -1,11 +1,9 @@ package org.junit.rules; /** - * "Fake" class used as a replacement for Junit4-dependent classes. - * See more at: - * GenericContainer run from Jupiter tests shouldn't require JUnit 4.x library on runtime classpath - * . + * "Fake" class used as a replacement for Junit4-dependent classes. See more at: GenericContainer run from + * Jupiter tests shouldn't require JUnit 4.x library on runtime classpath . */ @SuppressWarnings("unused") -public interface TestRule { -} \ No newline at end of file +public interface TestRule {} diff --git a/src/test/java/org/junit/runners/model/Statement.java b/src/test/java/org/junit/runners/model/Statement.java index d269a9dd..61440254 100644 --- a/src/test/java/org/junit/runners/model/Statement.java +++ b/src/test/java/org/junit/runners/model/Statement.java @@ -1,12 +1,9 @@ - package org.junit.runners.model; /** - * "Fake" class used as a replacement for Junit4-dependent classes. - * See more at: - * GenericContainer run from Jupiter tests shouldn't require JUnit 4.x library on runtime classpath - * . + * "Fake" class used as a replacement for Junit4-dependent classes. See more at: GenericContainer run from + * Jupiter tests shouldn't require JUnit 4.x library on runtime classpath . */ @SuppressWarnings("unused") -public class Statement { -} \ No newline at end of file +public class Statement {} diff --git a/src/test/java/org/phoebus/channelfinder/AdditionalConfig.java b/src/test/java/org/phoebus/channelfinder/AdditionalConfig.java index 78ef5c55..da379e30 100644 --- a/src/test/java/org/phoebus/channelfinder/AdditionalConfig.java +++ b/src/test/java/org/phoebus/channelfinder/AdditionalConfig.java @@ -7,8 +7,8 @@ @TestConfiguration public class AdditionalConfig { - @Bean - public MeterRegistry registry() { - return new SimpleMeterRegistry(); - } + @Bean + public MeterRegistry registry() { + return new SimpleMeterRegistry(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/AuthorizationIT.java b/src/test/java/org/phoebus/channelfinder/AuthorizationIT.java index f087edd5..d6622a09 100644 --- a/src/test/java/org/phoebus/channelfinder/AuthorizationIT.java +++ b/src/test/java/org/phoebus/channelfinder/AuthorizationIT.java @@ -15,200 +15,333 @@ @WebMvcTest(AuthorizationService.class) @TestPropertySource(value = "classpath:application_test.properties") class AuthorizationIT { - @Autowired AuthorizationService authorizationService; - - Tag testTag = new Tag("testTag","valid"); - Property testProperty = new Property("testProperty","valid"); - Channel testChannel = new Channel("testChannel","valid"); - - /** - * - */ - @Test - @WithMockUser(username = "invalid", roles = "CF-ADMINS") - void adminIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is admin (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is admin (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is admin (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "valid", roles = "CF-ADMINS") - void adminAndDirectOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is admin and direct owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is admin and direct owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is admin and direct owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "invalid", roles = {"CF-ADMINS","VALID"}) - void adminAndGroupOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is admin and group owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is admin and group owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is admin and group owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "valid", roles = {"CF-ADMINS","VALID"}) - void adminAndDirectOwnerAndGroupOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is admin and direct owner and group owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is admin and direct owner and group owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is admin and direct owner and group owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "valid", roles = "") - void directOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is direct owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is direct owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is direct owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "invalid", roles = "VALID") - void groupOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is group owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is group owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is group owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "valid", roles = "VALID") - void directOwnerAndGroupOwnerIsAuthorizedOwner() { - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "failed to authorize user that is direct owner and group owner (tag)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "failed to authorize user that is direct owner and group owner (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "failed to authorize user that is direct owner and group owner (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(username = "invalid", roles = "") - void isNotAuthorizedOwner() { - Assertions.assertFalse(authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testTag), "authorized user that shouldn't be authorized (tag)"); - Assertions.assertFalse( authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testProperty), "authorized user that shouldn't be authorized (property)"); - Assertions.assertFalse( authorizationService.isAuthorizedOwner(SecurityContextHolder.getContext().getAuthentication(), testChannel), "authorized user that shouldn't be authorized (channel)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = "CF-ADMINS") - void adminIsAuthorizedRole() { - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "failed to authorize user that is admin (admin)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "failed to authorize user that is admin (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is admin (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is admin (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = {"CF-ADMINS","CF-TAGS"}) - void adminAndTagIsAuthorizedRole() { - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "failed to authorize user that is admin and tag (admin)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "failed to authorize user that is admin and tag (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is admin and tag (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is admin and tag (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = "CF-CHANNELS") - void channelIsAuthorizedRole() { - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is channel (admin)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "failed to authorize user that is channel (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is channel (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is channel (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = {"CF-CHANNELS","CF-TAGS"}) - void channelAndTagIsAuthorizedRole() { - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is channel and tag (admin)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "failed to authorize user that is channel and tag (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is channel and tag (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is channel and tag (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = "CF-PROPERTIES") - void propertyIsAuthorizedRole() { - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is property (admin)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "authorized user that is property (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is property (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is property (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = {"CF-PROPERTIES","CF-TAGS"}) - void propertyAndTagIsAuthorizedRole() { - Assertions.assertFalse( authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is property and tag (admin)"); - Assertions.assertFalse( authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "authorized user that is property and tag (channel)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "failed to authorize user that is property and tag (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is property and tag (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = "CF-TAGS") - void TagIsAuthorizedRole() { - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is tag (admin)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "authorized user that is tag (channel)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "authorized user that is tag (property)"); - Assertions.assertTrue(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "failed to authorize user that is tag (tag)"); - } - - /** - * - */ - @Test - @WithMockUser(roles = "") - void noneIsNotAuthorizedRole() { - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), "authorized user that is admin (admin)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), "authorized user that is admin (channel)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), "authorized user that is admin (property)"); - Assertions.assertFalse(authorizationService.isAuthorizedRole(SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), "authorized user that is admin (tag)"); - } -} + @Autowired AuthorizationService authorizationService; + + Tag testTag = new Tag("testTag", "valid"); + Property testProperty = new Property("testProperty", "valid"); + Channel testChannel = new Channel("testChannel", "valid"); + + /** */ + @Test + @WithMockUser(username = "invalid", roles = "CF-ADMINS") + void adminIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is admin (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is admin (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is admin (channel)"); + } + + /** */ + @Test + @WithMockUser(username = "valid", roles = "CF-ADMINS") + void adminAndDirectOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is admin and direct owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is admin and direct owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is admin and direct owner (channel)"); + } + + /** */ + @Test + @WithMockUser( + username = "invalid", + roles = {"CF-ADMINS", "VALID"}) + void adminAndGroupOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is admin and group owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is admin and group owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is admin and group owner (channel)"); + } + + /** */ + @Test + @WithMockUser( + username = "valid", + roles = {"CF-ADMINS", "VALID"}) + void adminAndDirectOwnerAndGroupOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is admin and direct owner and group owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is admin and direct owner and group owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is admin and direct owner and group owner (channel)"); + } + /** */ + @Test + @WithMockUser(username = "valid", roles = "") + void directOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is direct owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is direct owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is direct owner (channel)"); + } + /** */ + @Test + @WithMockUser(username = "invalid", roles = "VALID") + void groupOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is group owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is group owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is group owner (channel)"); + } + /** */ + @Test + @WithMockUser(username = "valid", roles = "VALID") + void directOwnerAndGroupOwnerIsAuthorizedOwner() { + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "failed to authorize user that is direct owner and group owner (tag)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "failed to authorize user that is direct owner and group owner (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "failed to authorize user that is direct owner and group owner (channel)"); + } + /** */ + @Test + @WithMockUser(username = "invalid", roles = "") + void isNotAuthorizedOwner() { + Assertions.assertFalse( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testTag), + "authorized user that shouldn't be authorized (tag)"); + Assertions.assertFalse( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testProperty), + "authorized user that shouldn't be authorized (property)"); + Assertions.assertFalse( + authorizationService.isAuthorizedOwner( + SecurityContextHolder.getContext().getAuthentication(), testChannel), + "authorized user that shouldn't be authorized (channel)"); + } + /** */ + @Test + @WithMockUser(roles = "CF-ADMINS") + void adminIsAuthorizedRole() { + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "failed to authorize user that is admin (admin)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "failed to authorize user that is admin (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is admin (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is admin (tag)"); + } + /** */ + @Test + @WithMockUser(roles = {"CF-ADMINS", "CF-TAGS"}) + void adminAndTagIsAuthorizedRole() { + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "failed to authorize user that is admin and tag (admin)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "failed to authorize user that is admin and tag (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is admin and tag (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is admin and tag (tag)"); + } + /** */ + @Test + @WithMockUser(roles = "CF-CHANNELS") + void channelIsAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is channel (admin)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "failed to authorize user that is channel (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is channel (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is channel (tag)"); + } + + /** */ + @Test + @WithMockUser(roles = {"CF-CHANNELS", "CF-TAGS"}) + void channelAndTagIsAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is channel and tag (admin)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "failed to authorize user that is channel and tag (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is channel and tag (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is channel and tag (tag)"); + } + + /** */ + @Test + @WithMockUser(roles = "CF-PROPERTIES") + void propertyIsAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is property (admin)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "authorized user that is property (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is property (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is property (tag)"); + } + + /** */ + @Test + @WithMockUser(roles = {"CF-PROPERTIES", "CF-TAGS"}) + void propertyAndTagIsAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is property and tag (admin)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "authorized user that is property and tag (channel)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "failed to authorize user that is property and tag (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is property and tag (tag)"); + } + + /** */ + @Test + @WithMockUser(roles = "CF-TAGS") + void TagIsAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is tag (admin)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "authorized user that is tag (channel)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "authorized user that is tag (property)"); + Assertions.assertTrue( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "failed to authorize user that is tag (tag)"); + } + + /** */ + @Test + @WithMockUser(roles = "") + void noneIsNotAuthorizedRole() { + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_ADMIN), + "authorized user that is admin (admin)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_CHANNEL), + "authorized user that is admin (channel)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_PROPERTY), + "authorized user that is admin (property)"); + Assertions.assertFalse( + authorizationService.isAuthorizedRole( + SecurityContextHolder.getContext().getAuthentication(), ROLES.CF_TAG), + "authorized user that is admin (tag)"); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/ChannelManagerIT.java b/src/test/java/org/phoebus/channelfinder/ChannelManagerIT.java index 0d2222db..dd3fd584 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelManagerIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelManagerIT.java @@ -1,6 +1,11 @@ package org.phoebus.channelfinder; import com.google.common.collect.Iterables; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -17,449 +22,535 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelManager.class) @WithMockUser(roles = "CF-ADMINS") @TestPropertySource(value = "classpath:application_test.properties") class ChannelManagerIT { - @Autowired - ChannelManager channelManager; - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - /** - * read a single channel - */ - @Test - void readXmlChannel() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel0); - - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - - Channel readChannel = channelManager.read(createdChannel.getName()); - // verify the channel was read as expected - Assertions.assertEquals(createdChannel, readChannel, "Failed to read the channel"); - } + @Autowired ChannelManager channelManager; - /** - * attempt to read a single non existent channel - */ - @Test - void readNonExistingXmlChannel() { - // verify the channel failed to be read, as expected - Assertions.assertThrows(ResponseStatusException.class, () -> channelManager.read("fakeChannel")); - } - - /** - * create a simple channel - */ - @Test - void createXmlChannel() { - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - cleanupTestChannels = Arrays.asList(testChannel0); - - // Create a simple channel - Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); - // verify the channel was created as expected - Assertions.assertEquals(testChannel0, createdChannel0, "Failed to create the channel"); - -// Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); -// // verify the tag was created as expected -// assertEquals("Failed to create the tag",testTag1,createdTag1); - - // Update the test channel with a new owner - testChannel0.setOwner("updateTestOwner"); - Channel updatedChannel0 = channelManager.create(testChannel0.getName(), testChannel0); - // verify the channel was created as expected - Assertions.assertEquals(testChannel0, updatedChannel0, "Failed to create the channel"); - } + @Autowired TagRepository tagRepository; - /** - * Rename a simple channel using create - */ - @Test - void renameByCreateXmlChannel() { - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - Channel testChannel1 = new Channel("testChannel1", "testOwner"); - cleanupTestChannels = Arrays.asList(testChannel0,testChannel1); - - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - createdChannel = channelManager.create(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 - Assertions.assertFalse(channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); - } - - /** - * create a single channel with tags and properties - */ - @Test - void createXmlChannel2() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel0); - - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - try { - Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); - Assertions.assertEquals(testChannel0, foundChannel, "Failed to create the channel. Expected " + testChannel0.toLog() + " found " - + foundChannel.toLog()); - } catch (Exception e) { - Assertions.fail("Failed to create/find the channel"); - } - -// Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); -// // verify the tag was created as expected -// assertEquals("Failed to create the tag",testTag1,createdTag1); - - // Update the test channel with a new owner - testChannel0.setOwner("updateTestOwner"); - createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - try { - Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); - Assertions.assertEquals(testChannel0, foundChannel, "Failed to create the channel. Expected " + testChannel0.toLog() + " found " - + foundChannel.toLog()); - } catch (Exception e) { - Assertions.fail("Failed to create/find the channel"); - } - } - - /** - * Rename a single channel with tags and properties using create - */ - @Test - void renameByCreateXmlChannel2() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1", "testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel0,testChannel1); - - // Create the testChannel0 - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - // update the testChannel0 with testChannel1 - createdChannel = channelManager.create(testChannel0.getName(), testChannel1); - // verify that the old channel "testChannel0" was replaced with the new "testChannel1" - try { - Channel foundChannel = channelRepository.findById(testChannel1.getName()).get(); - Assertions.assertEquals(testChannel1, foundChannel, "Failed to create the channel"); - } catch (Exception e) { - Assertions.fail("Failed to create/find the channel"); - } - // verify that the old channel is no longer present - Assertions.assertFalse(channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); - } - - /** - * create multiple channels - */ - @Test - void createXmlChannels() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1", "testOwner",testProperties,testTags); - Channel testChannel2 = new Channel("testChannel2", "testOwner"); - List testChannels = Arrays.asList(testChannel0,testChannel1,testChannel2); - cleanupTestChannels = testChannels; - - Iterable createdChannels = channelManager.create(testChannels); - List foundChannels = new ArrayList(); - testChannels.forEach(chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); - // verify the channels were created as expected - Assertions.assertTrue(Iterables.elementsEqual(testChannels, foundChannels), "Failed to create the channels"); - } + @Autowired PropertyRepository propertyRepository; - /** - * create by overriding multiple channels - */ - @Test - void createXmlChannelsWithOverride() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - Channel testChannel1 = new Channel("testChannel1", "testOwner",testProperties,testTags); - List testChannels = Arrays.asList(testChannel0,testChannel1); - cleanupTestChannels = testChannels; - - //Create a set of original channels to be overriden - channelManager.create(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); - List foundChannels = new ArrayList(); - testChannels.forEach(chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); - // verify the channels were created as expected - Assertions.assertTrue(Iterables.elementsEqual(updatedTestChannels, foundChannels), "Failed to create the channels"); - } - - /** - * update a channel - */ - @Test - void updateXmlChannel() { - testProperties.forEach(prop -> prop.setValue("value")); - // A test channel with only name and owner - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - // A test channel with name, owner, tags and props - Channel testChannel1 = new Channel("testChannel1", "testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel0,testChannel1); - - // 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); - Assertions.assertEquals(testChannel0, returnedChannel, "Failed to update channel " + testChannel0); - Assertions.assertEquals(testChannel0, channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); - // 2. Test a channel with tags and props - returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); - Assertions.assertEquals(testChannel1, returnedChannel, "Failed to update channel " + testChannel1); - Assertions.assertEquals(testChannel1, channelRepository.findById(testChannel1.getName()).get(), "Failed to update channel " + testChannel1); - - // Update the channel owner - testChannel0.setOwner("newTestOwner"); - returnedChannel = channelManager.update(testChannel0.getName(), testChannel0); - Assertions.assertEquals(testChannel0, returnedChannel, "Failed to update channel " + testChannel0); - Assertions.assertEquals(testChannel0, channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); - testChannel1.setOwner("newTestOwner"); - returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); - Assertions.assertEquals(testChannel1, returnedChannel, "Failed to update channel " + testChannel1); - Assertions.assertEquals(testChannel1, channelRepository.findById(testChannel1.getName()).get(), "Failed to update channel " + testChannel1); - } - - /** - * Rename a channel using update - */ - @Test - void renameByUpdateXmlChannel() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - Channel testChannel1 = new Channel("testChannel1", "testOwner"); - Channel testChannel2 = new Channel("testChannel2", "testOwner",testProperties,testTags); - Channel testChannel3 = new Channel("testChannel3", "testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel0,testChannel1,testChannel2,testChannel3); - - // Create the testChannels - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - Channel createdChannelWithItems = channelManager.create(testChannel2.getName(), testChannel2); - // update the testChannels - Channel renamedChannel = channelManager.update(testChannel0.getName(), testChannel1); - Channel renamedChannelWithItems = channelManager.update(testChannel2.getName(), testChannel3); - - // verify that the old channels were replaced by the new ones - try { - Channel foundChannel = channelRepository.findById(testChannel1.getName()).get(); - Assertions.assertEquals(testChannel1, foundChannel, "Failed to create the channel"); - } catch (Exception e) { - Assertions.fail("Failed to create/find the channel"); - } - // verify that the old channel is no longer present - Assertions.assertFalse(channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); - - try { - Channel foundChannel = channelRepository.findById(testChannel3.getName()).get(); - Assertions.assertEquals(testChannel3, foundChannel, "Failed to create the channel"); - } catch (Exception e) { - Assertions.fail("Failed to create/find the channel"); - } - // verify that the old channel is no longer present - Assertions.assertFalse(channelRepository.existsById(testChannel2.getName()), "Failed to replace the old channel"); - - // TODO add test for failure case + @Autowired ChannelRepository channelRepository; + + /** read a single channel */ + @Test + void readXmlChannel() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel0); + + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + + Channel readChannel = channelManager.read(createdChannel.getName()); + // verify the channel was read as expected + Assertions.assertEquals(createdChannel, readChannel, "Failed to read the channel"); + } + + /** attempt to read a single non existent channel */ + @Test + void readNonExistingXmlChannel() { + // verify the channel failed to be read, as expected + Assertions.assertThrows( + ResponseStatusException.class, () -> channelManager.read("fakeChannel")); + } + + /** create a simple channel */ + @Test + void createXmlChannel() { + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + cleanupTestChannels = Arrays.asList(testChannel0); + + // Create a simple channel + Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + // verify the channel was created as expected + Assertions.assertEquals(testChannel0, createdChannel0, "Failed to create the channel"); + + // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); + // // verify the tag was created as expected + // assertEquals("Failed to create the tag",testTag1,createdTag1); + + // Update the test channel with a new owner + testChannel0.setOwner("updateTestOwner"); + Channel updatedChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + // verify the channel was created as expected + Assertions.assertEquals(testChannel0, updatedChannel0, "Failed to create the channel"); + } + + /** Rename a simple channel using create */ + @Test + void renameByCreateXmlChannel() { + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + Channel testChannel1 = new Channel("testChannel1", "testOwner"); + cleanupTestChannels = Arrays.asList(testChannel0, testChannel1); + + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + createdChannel = channelManager.create(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 + Assertions.assertFalse( + channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); + } + + /** create a single channel with tags and properties */ + @Test + void createXmlChannel2() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel0); + + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + try { + Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); + Assertions.assertEquals( + testChannel0, + foundChannel, + "Failed to create the channel. Expected " + + testChannel0.toLog() + + " found " + + foundChannel.toLog()); + } catch (Exception e) { + Assertions.fail("Failed to create/find the channel"); } - - /** - * update a channel by adding tags and adding properties and changing properties - */ - @Test - void updateXmlChannelItems() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner", - Arrays.asList(testProperties.get(0),testProperties.get(1)),Arrays.asList(testTags.get(0),testTags.get(1))); - cleanupTestChannels = Arrays.asList(testChannel0); - - // Create the testChannel - Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); - - // set up the new testChannel - testProperties.get(1).setValue("newValue"); - testChannel0 = new Channel("testChannel0", "testOwner", - Arrays.asList(testProperties.get(1),testProperties.get(2)),Arrays.asList(testTags.get(1),testTags.get(2))); - - // update the testChannel - Channel updatedChannel = channelManager.update(testChannel0.getName(), testChannel0); - - Channel expectedChannel = new Channel("testChannel0", "testOwner",testProperties,testTags); - Channel foundChannel = channelRepository.findById("testChannel0").get(); - foundChannel.getTags().sort((Tag o1, Tag o2) -> { - return o1.getName().compareTo(o2.getName()); - }); - foundChannel.getProperties().sort((Property o1, Property o2) -> { - return o1.getName().compareTo(o2.getName()); - }); - Assertions.assertEquals(expectedChannel, foundChannel, "Did not update channel correctly, expected " + expectedChannel.toLog() + " but actual was " - + foundChannel.toLog()); + + // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); + // // verify the tag was created as expected + // assertEquals("Failed to create the tag",testTag1,createdTag1); + + // Update the test channel with a new owner + testChannel0.setOwner("updateTestOwner"); + createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + try { + Channel foundChannel = channelRepository.findById(testChannel0.getName()).get(); + Assertions.assertEquals( + testChannel0, + foundChannel, + "Failed to create the channel. Expected " + + testChannel0.toLog() + + " found " + + foundChannel.toLog()); + } catch (Exception e) { + Assertions.fail("Failed to create/find the channel"); } - - /** - * update multiple channels - * first update non-existing channels which should create them - * second update the newly created channels which should change them - */ - @Test - void updateMultipleXmlChannels() { - testProperties.forEach(prop -> prop.setValue("value")); - // A test channel with only name and owner - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - // A test channel with name, owner, tags and props - Channel testChannel1 = new Channel("testChannel1", "testOwner",testProperties,testTags); - List testChannels = Arrays.asList(testChannel0,testChannel1); - cleanupTestChannels = testChannels; - - // Update on non-existing channels should result in the creation of those channels - Iterable returnedChannels = channelManager.update(testChannels); - // 1. Test a simple channel - Assertions.assertEquals(testChannel0, channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); - // 2. Test a channel with tags and props - Assertions.assertEquals(testChannel1, channelRepository.findById(testChannel1.getName()).get(), "Failed to update channel " + testChannel1); - - // Update the channel owner - testChannel0.setOwner("newTestOwner"); - testChannel1.setOwner("newTestOwner"); - returnedChannels = channelManager.update(testChannels); - Assertions.assertEquals(testChannel0, channelRepository.findById(testChannel0.getName()).get(), "Failed to update channel " + testChannel0); - Assertions.assertEquals(testChannel1, channelRepository.findById(testChannel1.getName()).get(), "Failed to update channel " + testChannel1); + } + + /** Rename a single channel with tags and properties using create */ + @Test + void renameByCreateXmlChannel2() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel0, testChannel1); + + // Create the testChannel0 + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + // update the testChannel0 with testChannel1 + createdChannel = channelManager.create(testChannel0.getName(), testChannel1); + // verify that the old channel "testChannel0" was replaced with the new "testChannel1" + try { + Channel foundChannel = channelRepository.findById(testChannel1.getName()).get(); + Assertions.assertEquals(testChannel1, foundChannel, "Failed to create the channel"); + } catch (Exception e) { + Assertions.fail("Failed to create/find the channel"); } - - /** - * update multiple channels by adding tags and adding properties and changing properties - */ - @Test - void updateMultipleXmlChannelsWithItems() { - testProperties.forEach(prop -> prop.setValue("value")); - Channel testChannel0 = new Channel("testChannel0", "testOwner", - Arrays.asList(testProperties.get(0),testProperties.get(1)),Arrays.asList(testTags.get(0),testTags.get(1))); - Channel testChannel1 = new Channel("testChannel1", "testOwner", - Arrays.asList(testProperties.get(0),testProperties.get(2)),Arrays.asList(testTags.get(0),testTags.get(2))); - List testChannels = Arrays.asList(testChannel0,testChannel1); - cleanupTestChannels = testChannels; - - // Create the testChannel - Iterable createdChannels = channelManager.create(testChannels); - - // set up the new testChannel - testProperties.forEach(prop -> prop.setValue("newValue")); - testChannel0 = new Channel("testChannel0", "testOwner", - Arrays.asList(testProperties.get(0),testProperties.get(2)),Arrays.asList(testTags.get(0),testTags.get(2))); - testChannel1 = new Channel("testChannel1", "testOwner", - Arrays.asList(testProperties.get(0),testProperties.get(1)),Arrays.asList(testTags.get(0),testTags.get(1))); - testChannels = Arrays.asList(testChannel0,testChannel1); - - // update the testChannel - Iterable updatedChannels = channelManager.update(testChannels); - - // set up the expected testChannels - testChannel0 = new Channel("testChannel0", "testOwner", - Arrays.asList(testProperties.get(0),new Property("testProperty1", "testPropertyOwner1","value"),testProperties.get(2)), testTags); - testChannel1 = new Channel("testChannel1", "testOwner", - Arrays.asList(testProperties.get(0), testProperties.get(1), new Property("testProperty2", "testPropertyOwner2","value")), testTags); - Iterable expectedChannels = Arrays.asList(testChannel0,testChannel1); - - Iterable foundChannels = channelRepository.findAllById(Arrays.asList("testChannel0","testChannel1")); - foundChannels.forEach(chan -> chan.getTags().sort((Tag o1, Tag o2) -> { - return o1.getName().compareTo(o2.getName());})); - foundChannels.forEach(chan -> chan.getProperties().sort((Property o1, Property o2) -> { - return o1.getName().compareTo(o2.getName());})); - - Assertions.assertEquals(expectedChannels, foundChannels, "Did not update channel correctly, expected " + testChannel0.toLog() + " and " + testChannel1.toLog() + " but actual was " - + foundChannels.iterator().next().toLog() + " and " + foundChannels.iterator().next().toLog()); - } - - /** - * delete a channel - */ - @Test - void deleteXmlChannel() { - Channel testChannel0 = new Channel("testChannel0", "testOwner"); - cleanupTestChannels = Arrays.asList(testChannel0); - - channelManager.create(testChannel0.getName(),testChannel0); - channelManager.remove(testChannel0.getName()); - // verify the channel was deleted as expected - Assertions.assertFalse(channelRepository.existsById(testChannel0.getName()), "Failed to delete the channel"); + // verify that the old channel is no longer present + Assertions.assertFalse( + channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); + } + + /** create multiple channels */ + @Test + void createXmlChannels() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner", testProperties, testTags); + Channel testChannel2 = new Channel("testChannel2", "testOwner"); + List testChannels = Arrays.asList(testChannel0, testChannel1, testChannel2); + cleanupTestChannels = testChannels; + + Iterable createdChannels = channelManager.create(testChannels); + List foundChannels = new ArrayList(); + testChannels.forEach( + chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); + // verify the channels were created as expected + Assertions.assertTrue( + Iterables.elementsEqual(testChannels, foundChannels), "Failed to create the channels"); + } + + /** create by overriding multiple channels */ + @Test + void createXmlChannelsWithOverride() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + Channel testChannel1 = new Channel("testChannel1", "testOwner", testProperties, testTags); + List testChannels = Arrays.asList(testChannel0, testChannel1); + cleanupTestChannels = testChannels; + + // Create a set of original channels to be overriden + channelManager.create(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); + List foundChannels = new ArrayList(); + testChannels.forEach( + chan -> foundChannels.add(channelRepository.findById(chan.getName()).get())); + // verify the channels were created as expected + Assertions.assertTrue( + Iterables.elementsEqual(updatedTestChannels, foundChannels), + "Failed to create the channels"); + } + + /** update a channel */ + @Test + void updateXmlChannel() { + testProperties.forEach(prop -> prop.setValue("value")); + // A test channel with only name and owner + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + // A test channel with name, owner, tags and props + Channel testChannel1 = new Channel("testChannel1", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel0, testChannel1); + + // 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); + Assertions.assertEquals( + testChannel0, returnedChannel, "Failed to update channel " + testChannel0); + Assertions.assertEquals( + testChannel0, + channelRepository.findById(testChannel0.getName()).get(), + "Failed to update channel " + testChannel0); + // 2. Test a channel with tags and props + returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); + Assertions.assertEquals( + testChannel1, returnedChannel, "Failed to update channel " + testChannel1); + Assertions.assertEquals( + testChannel1, + channelRepository.findById(testChannel1.getName()).get(), + "Failed to update channel " + testChannel1); + + // Update the channel owner + testChannel0.setOwner("newTestOwner"); + returnedChannel = channelManager.update(testChannel0.getName(), testChannel0); + Assertions.assertEquals( + testChannel0, returnedChannel, "Failed to update channel " + testChannel0); + Assertions.assertEquals( + testChannel0, + channelRepository.findById(testChannel0.getName()).get(), + "Failed to update channel " + testChannel0); + testChannel1.setOwner("newTestOwner"); + returnedChannel = channelManager.update(testChannel1.getName(), testChannel1); + Assertions.assertEquals( + testChannel1, returnedChannel, "Failed to update channel " + testChannel1); + Assertions.assertEquals( + testChannel1, + channelRepository.findById(testChannel1.getName()).get(), + "Failed to update channel " + testChannel1); + } + + /** Rename a channel using update */ + @Test + void renameByUpdateXmlChannel() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + Channel testChannel1 = new Channel("testChannel1", "testOwner"); + Channel testChannel2 = new Channel("testChannel2", "testOwner", testProperties, testTags); + Channel testChannel3 = new Channel("testChannel3", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel0, testChannel1, testChannel2, testChannel3); + + // Create the testChannels + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + Channel createdChannelWithItems = channelManager.create(testChannel2.getName(), testChannel2); + // update the testChannels + Channel renamedChannel = channelManager.update(testChannel0.getName(), testChannel1); + Channel renamedChannelWithItems = channelManager.update(testChannel2.getName(), testChannel3); + + // verify that the old channels were replaced by the new ones + try { + Channel foundChannel = channelRepository.findById(testChannel1.getName()).get(); + Assertions.assertEquals(testChannel1, foundChannel, "Failed to create the channel"); + } catch (Exception e) { + Assertions.fail("Failed to create/find the channel"); } - - // Helper operations to create and clean up the resources needed for successful - // testing of the ChannelManager operations - - private final List testTags = Arrays.asList( - new Tag("testTag0", "testTagOwner0"), - new Tag("testTag1", "testTagOwner1"), - new Tag("testTag2", "testTagOwner2")); - - private final List testProperties = Arrays.asList( - new Property("testProperty0", "testPropertyOwner0"), - new Property("testProperty1", "testPropertyOwner1"), - new Property("testProperty2", "testPropertyOwner2")); - - private List cleanupTestChannels = Collections.emptyList(); - - @BeforeEach - public void setup() { - tagRepository.indexAll(testTags); - propertyRepository.indexAll(testProperties); + // verify that the old channel is no longer present + Assertions.assertFalse( + channelRepository.existsById(testChannel0.getName()), "Failed to replace the old channel"); + + try { + Channel foundChannel = channelRepository.findById(testChannel3.getName()).get(); + Assertions.assertEquals(testChannel3, foundChannel, "Failed to create the channel"); + } catch (Exception e) { + Assertions.fail("Failed to create/find the channel"); } - @AfterEach - public void cleanup() { - // clean up - testTags.forEach(tag -> { - try { - tagRepository.deleteById(tag.getName()); - } catch (Exception e) { - System.out.println("Failed to clean up tag: " + tag.getName()); - } + // verify that the old channel is no longer present + Assertions.assertFalse( + channelRepository.existsById(testChannel2.getName()), "Failed to replace the old channel"); + + // TODO add test for failure case + } + + /** update a channel by adding tags and adding properties and changing properties */ + @Test + void updateXmlChannelItems() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = + new Channel( + "testChannel0", + "testOwner", + Arrays.asList(testProperties.get(0), testProperties.get(1)), + Arrays.asList(testTags.get(0), testTags.get(1))); + cleanupTestChannels = Arrays.asList(testChannel0); + + // Create the testChannel + Channel createdChannel = channelManager.create(testChannel0.getName(), testChannel0); + + // set up the new testChannel + testProperties.get(1).setValue("newValue"); + testChannel0 = + new Channel( + "testChannel0", + "testOwner", + Arrays.asList(testProperties.get(1), testProperties.get(2)), + Arrays.asList(testTags.get(1), testTags.get(2))); + + // update the testChannel + Channel updatedChannel = channelManager.update(testChannel0.getName(), testChannel0); + + Channel expectedChannel = new Channel("testChannel0", "testOwner", testProperties, testTags); + Channel foundChannel = channelRepository.findById("testChannel0").get(); + foundChannel + .getTags() + .sort( + (Tag o1, Tag o2) -> { + return o1.getName().compareTo(o2.getName()); + }); + foundChannel + .getProperties() + .sort( + (Property o1, Property o2) -> { + return o1.getName().compareTo(o2.getName()); + }); + Assertions.assertEquals( + expectedChannel, + foundChannel, + "Did not update channel correctly, expected " + + expectedChannel.toLog() + + " but actual was " + + foundChannel.toLog()); + } + + /** + * update multiple channels first update non-existing channels which should create them second + * update the newly created channels which should change them + */ + @Test + void updateMultipleXmlChannels() { + testProperties.forEach(prop -> prop.setValue("value")); + // A test channel with only name and owner + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + // A test channel with name, owner, tags and props + Channel testChannel1 = new Channel("testChannel1", "testOwner", testProperties, testTags); + List testChannels = Arrays.asList(testChannel0, testChannel1); + cleanupTestChannels = testChannels; + + // Update on non-existing channels should result in the creation of those channels + Iterable returnedChannels = channelManager.update(testChannels); + // 1. Test a simple channel + Assertions.assertEquals( + testChannel0, + channelRepository.findById(testChannel0.getName()).get(), + "Failed to update channel " + testChannel0); + // 2. Test a channel with tags and props + Assertions.assertEquals( + testChannel1, + channelRepository.findById(testChannel1.getName()).get(), + "Failed to update channel " + testChannel1); + + // Update the channel owner + testChannel0.setOwner("newTestOwner"); + testChannel1.setOwner("newTestOwner"); + returnedChannels = channelManager.update(testChannels); + Assertions.assertEquals( + testChannel0, + channelRepository.findById(testChannel0.getName()).get(), + "Failed to update channel " + testChannel0); + Assertions.assertEquals( + testChannel1, + channelRepository.findById(testChannel1.getName()).get(), + "Failed to update channel " + testChannel1); + } + + /** update multiple channels by adding tags and adding properties and changing properties */ + @Test + void updateMultipleXmlChannelsWithItems() { + testProperties.forEach(prop -> prop.setValue("value")); + Channel testChannel0 = + new Channel( + "testChannel0", + "testOwner", + Arrays.asList(testProperties.get(0), testProperties.get(1)), + Arrays.asList(testTags.get(0), testTags.get(1))); + Channel testChannel1 = + new Channel( + "testChannel1", + "testOwner", + Arrays.asList(testProperties.get(0), testProperties.get(2)), + Arrays.asList(testTags.get(0), testTags.get(2))); + List testChannels = Arrays.asList(testChannel0, testChannel1); + cleanupTestChannels = testChannels; + + // Create the testChannel + Iterable createdChannels = channelManager.create(testChannels); + + // set up the new testChannel + testProperties.forEach(prop -> prop.setValue("newValue")); + testChannel0 = + new Channel( + "testChannel0", + "testOwner", + Arrays.asList(testProperties.get(0), testProperties.get(2)), + Arrays.asList(testTags.get(0), testTags.get(2))); + testChannel1 = + new Channel( + "testChannel1", + "testOwner", + Arrays.asList(testProperties.get(0), testProperties.get(1)), + Arrays.asList(testTags.get(0), testTags.get(1))); + testChannels = Arrays.asList(testChannel0, testChannel1); + + // update the testChannel + Iterable updatedChannels = channelManager.update(testChannels); + + // set up the expected testChannels + testChannel0 = + new Channel( + "testChannel0", + "testOwner", + Arrays.asList( + testProperties.get(0), + new Property("testProperty1", "testPropertyOwner1", "value"), + testProperties.get(2)), + testTags); + testChannel1 = + new Channel( + "testChannel1", + "testOwner", + Arrays.asList( + testProperties.get(0), + testProperties.get(1), + new Property("testProperty2", "testPropertyOwner2", "value")), + testTags); + Iterable expectedChannels = Arrays.asList(testChannel0, testChannel1); + + Iterable foundChannels = + channelRepository.findAllById(Arrays.asList("testChannel0", "testChannel1")); + foundChannels.forEach( + chan -> + chan.getTags() + .sort( + (Tag o1, Tag o2) -> { + return o1.getName().compareTo(o2.getName()); + })); + foundChannels.forEach( + chan -> + chan.getProperties() + .sort( + (Property o1, Property o2) -> { + return o1.getName().compareTo(o2.getName()); + })); + + Assertions.assertEquals( + expectedChannels, + foundChannels, + "Did not update channel correctly, expected " + + testChannel0.toLog() + + " and " + + testChannel1.toLog() + + " but actual was " + + foundChannels.iterator().next().toLog() + + " and " + + foundChannels.iterator().next().toLog()); + } + + /** delete a channel */ + @Test + void deleteXmlChannel() { + Channel testChannel0 = new Channel("testChannel0", "testOwner"); + cleanupTestChannels = Arrays.asList(testChannel0); + + channelManager.create(testChannel0.getName(), testChannel0); + channelManager.remove(testChannel0.getName()); + // verify the channel was deleted as expected + Assertions.assertFalse( + channelRepository.existsById(testChannel0.getName()), "Failed to delete the channel"); + } + + // Helper operations to create and clean up the resources needed for successful + // testing of the ChannelManager operations + + private final List testTags = + Arrays.asList( + new Tag("testTag0", "testTagOwner0"), + new Tag("testTag1", "testTagOwner1"), + new Tag("testTag2", "testTagOwner2")); + + private final List testProperties = + Arrays.asList( + new Property("testProperty0", "testPropertyOwner0"), + new Property("testProperty1", "testPropertyOwner1"), + new Property("testProperty2", "testPropertyOwner2")); + + private List cleanupTestChannels = Collections.emptyList(); + + @BeforeEach + public void setup() { + tagRepository.indexAll(testTags); + propertyRepository.indexAll(testProperties); + } + + @AfterEach + public void cleanup() { + // clean up + testTags.forEach( + tag -> { + try { + tagRepository.deleteById(tag.getName()); + } catch (Exception e) { + System.out.println("Failed to clean up tag: " + tag.getName()); + } }); - testProperties.forEach(property -> { - try { - propertyRepository.deleteById(property.getName()); - } catch (Exception e) { - System.out.println("Failed to clean up property: " + property.getName()); - } + testProperties.forEach( + property -> { + try { + propertyRepository.deleteById(property.getName()); + } catch (Exception e) { + System.out.println("Failed to clean up property: " + property.getName()); + } }); - cleanupTestChannels.forEach(channel -> { - if (channelRepository.existsById(channel.getName())) { - channelRepository.deleteById(channel.getName()); - } + cleanupTestChannels.forEach( + channel -> { + if (channelRepository.existsById(channel.getName())) { + channelRepository.deleteById(channel.getName()); + } }); - } + } + @Autowired ElasticConfig esService; - @Autowired - ElasticConfig esService; + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } -} \ No newline at end of file + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/ChannelRepositoryIT.java b/src/test/java/org/phoebus/channelfinder/ChannelRepositoryIT.java index ba054295..909c6499 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelRepositoryIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelRepositoryIT.java @@ -2,6 +2,12 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -16,504 +22,551 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; - import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelRepository.class) @TestPropertySource(value = "classpath:application_test.properties") class ChannelRepositoryIT { - @Autowired - ElasticConfig esService; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } - /** - * index a single channel - */ - @Test - void indexXmlChannel() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel); - - Channel createdChannel = channelRepository.index(testChannel); - // verify the channel was created as expected - Assertions.assertEquals(testChannel, createdChannel, "Failed to create the channel"); - } - - /** - * index multiple channels - */ - @Test - void indexXmlChannels() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - List testChannels = Arrays.asList(testChannel, testChannel1); - cleanupTestChannels = testChannels; - - Iterable createdChannels = channelRepository.indexAll(testChannels); - // verify the channels were created as expected - Assertions.assertTrue(Iterables.elementsEqual(testChannels, createdChannels), "Failed to create the channels"); - } - - /** - * save a single channel - */ - @Test - void saveXmlChannel() { - Channel testChannel = new Channel("testChannel","testOwner"); - Channel updateTestChannel = - new Channel("testChannel","updateTestOwner", testProperties.subList(0,1), testTags.subList(0,1)); - Channel updateTestChannel1 = - new Channel("testChannel","updateTestOwner", testProperties.subList(1,2), testTags.subList(1,2)); - Channel updateTestChannel2 = - new Channel("updateTestChannel1","updateTestOwner1",testUpdatedProperties, testUpdatedTags); - Channel createdChannel = channelRepository.index(testChannel); - cleanupTestChannels = Arrays.asList(testChannel, updateTestChannel, updateTestChannel1, updateTestChannel2); - - // Update Channel with new owner a new property and a new tag - Channel updatedTestChannel = channelRepository.save(updateTestChannel); - // verify that the channel was updated as expected - Assertions.assertEquals(updateTestChannel, updatedTestChannel, "Failed to update the channel with the same name"); - - // Update Channel with a second property and tag - Channel updatedTestChannel1 = channelRepository.save(updateTestChannel1); - // verify that the channel was updated with the new tags and properties while preserving the old ones - Channel expectedChannel = new Channel("testChannel","updateTestOwner"); - expectedChannel.addProperties(testProperties); - expectedChannel.addTags(testTags); - Assertions.assertEquals(updateTestChannel, updatedTestChannel, "Failed to update the channel with the same name"); - } - - - /** - * save multiple channels - */ - @Test - void saveXmlChannels() { - Channel testChannel = new Channel("testChannel","testOwner", testProperties, testTags); - Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); - Channel updateTestChannel = new Channel("testChannel", "updateTestOwner", testUpdatedProperties, testUpdatedTags); - Channel updateTestChannel1 = new Channel("testChannel1", "updateTestOwner1", testUpdatedProperties, testUpdatedTags); - List testChannels = Arrays.asList(testChannel,testChannel1); - List updateTestChannels = Arrays.asList(updateTestChannel,updateTestChannel1); - Iterable createdChannels = channelRepository.indexAll(testChannels); - cleanupTestChannels = Arrays.asList(testChannel,testChannel1,updateTestChannel,updateTestChannel1); - - Iterable updatedTestChannels = channelRepository.saveAll(updateTestChannels); - // verify the channels were updated as expected - List expectedChannels = Arrays.asList( - new Channel("testChannel","updateTestOwner", testUpdatedProperties, testUpdatedTags), - new Channel("testChannel1","updateTestOwner1", testUpdatedProperties, testUpdatedTags) - ); - Assertions.assertEquals(expectedChannels, updatedTestChannels, "Failed to update the channels: "); + @Autowired ElasticConfig esService; + + @Autowired ChannelRepository channelRepository; + + @Autowired TagRepository tagRepository; + + @Autowired PropertyRepository propertyRepository; + + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } + + /** index a single channel */ + @Test + void indexXmlChannel() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel); + + Channel createdChannel = channelRepository.index(testChannel); + // verify the channel was created as expected + Assertions.assertEquals(testChannel, createdChannel, "Failed to create the channel"); + } + + /** index multiple channels */ + @Test + void indexXmlChannels() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + cleanupTestChannels = testChannels; + + Iterable createdChannels = channelRepository.indexAll(testChannels); + // verify the channels were created as expected + Assertions.assertTrue( + Iterables.elementsEqual(testChannels, createdChannels), "Failed to create the channels"); + } + + /** save a single channel */ + @Test + void saveXmlChannel() { + Channel testChannel = new Channel("testChannel", "testOwner"); + Channel updateTestChannel = + new Channel( + "testChannel", "updateTestOwner", testProperties.subList(0, 1), testTags.subList(0, 1)); + Channel updateTestChannel1 = + new Channel( + "testChannel", "updateTestOwner", testProperties.subList(1, 2), testTags.subList(1, 2)); + Channel updateTestChannel2 = + new Channel( + "updateTestChannel1", "updateTestOwner1", testUpdatedProperties, testUpdatedTags); + Channel createdChannel = channelRepository.index(testChannel); + cleanupTestChannels = + Arrays.asList(testChannel, updateTestChannel, updateTestChannel1, updateTestChannel2); + + // Update Channel with new owner a new property and a new tag + Channel updatedTestChannel = channelRepository.save(updateTestChannel); + // verify that the channel was updated as expected + Assertions.assertEquals( + updateTestChannel, updatedTestChannel, "Failed to update the channel with the same name"); + + // Update Channel with a second property and tag + Channel updatedTestChannel1 = channelRepository.save(updateTestChannel1); + // verify that the channel was updated with the new tags and properties while preserving the old + // ones + Channel expectedChannel = new Channel("testChannel", "updateTestOwner"); + expectedChannel.addProperties(testProperties); + expectedChannel.addTags(testTags); + Assertions.assertEquals( + updateTestChannel, updatedTestChannel, "Failed to update the channel with the same name"); + } + + /** save multiple channels */ + @Test + void saveXmlChannels() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + Channel updateTestChannel = + new Channel("testChannel", "updateTestOwner", testUpdatedProperties, testUpdatedTags); + Channel updateTestChannel1 = + new Channel("testChannel1", "updateTestOwner1", testUpdatedProperties, testUpdatedTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + List updateTestChannels = Arrays.asList(updateTestChannel, updateTestChannel1); + Iterable createdChannels = channelRepository.indexAll(testChannels); + cleanupTestChannels = + Arrays.asList(testChannel, testChannel1, updateTestChannel, updateTestChannel1); + + Iterable updatedTestChannels = channelRepository.saveAll(updateTestChannels); + // verify the channels were updated as expected + List expectedChannels = + Arrays.asList( + new Channel("testChannel", "updateTestOwner", testUpdatedProperties, testUpdatedTags), + new Channel( + "testChannel1", "updateTestOwner1", testUpdatedProperties, testUpdatedTags)); + Assertions.assertEquals( + expectedChannels, updatedTestChannels, "Failed to update the channels: "); + } + + /** find a single channel */ + @Test + void findXmlChannel() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + cleanupTestChannels = Arrays.asList(testChannel); + + Optional notFoundChannel = channelRepository.findById(testChannel.getName()); + // verify the channel was not found as expected + Assertions.assertNotEquals(Optional.of(testChannel), notFoundChannel, "Found the channel"); + + Channel createdChannel = channelRepository.index(testChannel); + + Optional foundChannel = channelRepository.findById(createdChannel.getName()); + // verify the channel was found as expected + if (foundChannel.isPresent()) { + Assertions.assertEquals(createdChannel, foundChannel.get(), "Failed to find the channel"); + } else Assertions.fail("Failed to find the channel"); + } + + /** check if a channel exists */ + @Test + void testChannelExists() { + Iterable createdTags = tagRepository.indexAll(testTags); + Iterable createdProperties = propertyRepository.indexAll(testProperties); + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel createdChannel = channelRepository.index(testChannel); + cleanupTestChannels = Arrays.asList(testChannel); + + // verify the channel exists as expected + Assertions.assertTrue( + channelRepository.existsById(testChannel.getName()), + "Failed to check the existance of " + testChannel.getName()); + // verify the channel does not exist, as expected + Assertions.assertFalse( + channelRepository.existsById("non-existant-channel"), + "Failed to check the non-existance of 'non-existant-channel'"); + } + + /** check if channels exist */ + @Test + void testChannelsExist() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + Iterable createdChannels = channelRepository.indexAll(testChannels); + cleanupTestChannels = Arrays.asList(testChannel, testChannel1); + + // verify the channels exist as expected + Assertions.assertTrue( + channelRepository.existsByIds(Arrays.asList("testChannel", "testChannel1")), + "Failed to check the existance of channels"); + // verify the channel does not exist, as expected + Assertions.assertFalse( + channelRepository.existsByIds(Arrays.asList("test-channel1", "non-existant-channel")), + "Failed to check the non-existance of 'non-existant-channel'"); + } + + /** find multiple channels */ + @Test + void findXmlChannels() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + List channelNames = Arrays.asList(testChannel.getName(), testChannel1.getName()); + Iterable notFoundChannels = null; + Iterable foundChannels = null; + + try { + notFoundChannels = channelRepository.findAllById(channelNames); + } catch (ResponseStatusException e) { + } finally { + // verify the channels were not found as expected + Assertions.assertNotEquals(testChannels, notFoundChannels, "Found the channels"); } - /** - * find a single channel - */ - @Test - void findXmlChannel() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - cleanupTestChannels = Arrays.asList(testChannel); - - Optional notFoundChannel = channelRepository.findById(testChannel.getName()); - // verify the channel was not found as expected - Assertions.assertNotEquals(Optional.of(testChannel), notFoundChannel, "Found the channel"); - - Channel createdChannel = channelRepository.index(testChannel); - - Optional foundChannel = channelRepository.findById(createdChannel.getName()); - // verify the channel was found as expected - if(foundChannel.isPresent()) { - Assertions.assertEquals(createdChannel, foundChannel.get(), "Failed to find the channel"); - } - else - Assertions.fail("Failed to find the channel"); - } + Iterable createdChannels = channelRepository.indexAll(testChannels); + cleanupTestChannels = Arrays.asList(testChannel, testChannel1); - /** - * check if a channel exists - */ - @Test - void testChannelExists() { - Iterable createdTags = tagRepository.indexAll(testTags); - Iterable createdProperties = propertyRepository.indexAll(testProperties); - Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); - Channel createdChannel = channelRepository.index(testChannel); - cleanupTestChannels = Arrays.asList(testChannel); - - // verify the channel exists as expected - Assertions.assertTrue(channelRepository.existsById(testChannel.getName()), "Failed to check the existance of " + testChannel.getName()); - // verify the channel does not exist, as expected - Assertions.assertFalse(channelRepository.existsById("non-existant-channel"), "Failed to check the non-existance of 'non-existant-channel'"); + try { + foundChannels = channelRepository.findAllById(channelNames); + } catch (ResponseStatusException e) { + } finally { + // verify the channels were found as expected + Assertions.assertEquals(createdChannels, foundChannels, "Failed to find the tags"); } - - /** - * check if channels exist - */ - @Test - void testChannelsExist() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - List testChannels = Arrays.asList(testChannel, testChannel1); - Iterable createdChannels = channelRepository.indexAll(testChannels); - cleanupTestChannels = Arrays.asList(testChannel,testChannel1); - - // verify the channels exist as expected - Assertions.assertTrue(channelRepository.existsByIds(Arrays.asList("testChannel", "testChannel1")), "Failed to check the existance of channels"); - // verify the channel does not exist, as expected - Assertions.assertFalse(channelRepository.existsByIds(Arrays.asList("test-channel1", "non-existant-channel")), "Failed to check the non-existance of 'non-existant-channel'"); + } + + /** find channels using case insensitive tag and property names searches */ + @Test + void findChannels() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + SearchResult foundChannelsResponse = null; + + List createdChannels = channelRepository.indexAll(testChannels); + SearchResult createdSearchResult = new SearchResult(createdChannels, 2); + cleanupTestChannels = Arrays.asList(testChannel, testChannel1); + + try { + MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + searchParameters.set(testProperties.get(0).getName().toLowerCase(), "*"); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on property name search (all lower case)"); + + searchParameters.set(testProperties.get(0).getName().toUpperCase(), "*"); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on property name search (all upper case)"); + + searchParameters.clear(); + searchParameters.set("~tag", testTags.get(0).getName().toLowerCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on tags name search (all lower case)"); + + searchParameters.set("~tag", testTags.get(0).getName().toUpperCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on tags name search (all upper case)"); + + } catch (ResponseStatusException e) { + Assertions.fail(e); } - - /** - * find multiple channels - */ - @Test - void findXmlChannels() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - List testChannels = Arrays.asList(testChannel, testChannel1); - List channelNames = Arrays.asList(testChannel.getName(),testChannel1.getName()); - Iterable notFoundChannels= null; - Iterable foundChannels = null; - - try { - notFoundChannels = channelRepository.findAllById(channelNames); - } catch (ResponseStatusException e) { - } finally { - // verify the channels were not found as expected - Assertions.assertNotEquals(testChannels, notFoundChannels, "Found the channels"); - } - - Iterable createdChannels = channelRepository.indexAll(testChannels); - cleanupTestChannels = Arrays.asList(testChannel,testChannel1); - - try { - foundChannels = channelRepository.findAllById(channelNames); - } catch (ResponseStatusException e) { - } finally { - // verify the channels were found as expected - Assertions.assertEquals(createdChannels, foundChannels, "Failed to find the tags"); - } + } + + /** find channels using not modifier */ + @Test + void findLackOfChannels() { + Property extraTestProperty = + new Property(testProperties.get(0).getName(), "testOwner", "value2"); + Channel testChannel = + new Channel("testChannel", "testOwner", List.of(testProperties.get(0)), testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + Channel testChannel2 = new Channel("testChannel2", "testOwner2", List.of(), List.of()); + Channel testChannel3 = + new Channel("testChannel3", "testOwner3", List.of(extraTestProperty), List.of()); + List testChannels = + Arrays.asList(testChannel, testChannel1, testChannel2, testChannel3); + SearchResult foundChannelsResponse = null; + + List createdChannels = channelRepository.indexAll(testChannels); + SearchResult createdSearchResult = new SearchResult(createdChannels, 4); + cleanupTestChannels = testChannels; + + try { + MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + searchParameters.set(testProperties.get(0).getName().toLowerCase() + "!", "*"); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + new SearchResult(List.of(createdChannels.get(2)), 1), foundChannelsResponse); + + } catch (ResponseStatusException e) { + Assertions.fail(e); } - - /** - * find channels using case insensitive tag and property names searches - */ - @Test - void findChannels() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - List testChannels = Arrays.asList(testChannel, testChannel1); - SearchResult foundChannelsResponse = null; - - List createdChannels = channelRepository.indexAll(testChannels); - SearchResult createdSearchResult = new SearchResult(createdChannels, 2); - cleanupTestChannels = Arrays.asList(testChannel,testChannel1); - - try { - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - searchParameters.set(testProperties.get(0).getName().toLowerCase(), "*"); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on property name search (all lower case)"); - - searchParameters.set(testProperties.get(0).getName().toUpperCase(), "*"); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on property name search (all upper case)"); - - searchParameters.clear(); - searchParameters.set("~tag", testTags.get(0).getName().toLowerCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on tags name search (all lower case)"); - - searchParameters.set("~tag", testTags.get(0).getName().toUpperCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on tags name search (all upper case)"); - - } catch (ResponseStatusException e) { - Assertions.fail(e); - } + } + + /** find channels using case insensitive names searches */ + @Test + void findChannelByCaseInsensitiveSearch() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel testChannel1 = new Channel("testChannel1", "testOwner1", testProperties, testTags); + List testChannels = Arrays.asList(testChannel, testChannel1); + SearchResult foundChannelsResponse = null; + + List createdChannels = channelRepository.indexAll(testChannels); + SearchResult createdSearchResult = new SearchResult(createdChannels, 2); + cleanupTestChannels = Arrays.asList(testChannel, testChannel1); + + try { + MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + + // Search for a single channel + searchParameters.set("~name", "testChannel"); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + new SearchResult(List.of(testChannel), 1), + foundChannelsResponse, + "Failed to find the based on channel name search (exact)"); + + searchParameters.set("~name", "testChannel".toLowerCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + new SearchResult(List.of(testChannel), 1), + foundChannelsResponse, + "Failed to find the based on channel name search (all lower case)"); + + searchParameters.set("~name", "testChannel".toUpperCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + new SearchResult(List.of(testChannel), 1), + foundChannelsResponse, + "Failed to find the based on channel name search (all upper case)"); + + // Search for multiple channels using case insensitive name searches + searchParameters.clear(); + searchParameters.set("~name", "testChannel*"); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on channel name search (exact)"); + + searchParameters.set("~name", "testChannel*".toLowerCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on channel name search (all lower case)"); + + searchParameters.set("~name", "testChannel*".toUpperCase()); + foundChannelsResponse = channelRepository.search(searchParameters); + Assertions.assertEquals( + createdSearchResult, + foundChannelsResponse, + "Failed to find the based on channel name search (all upper case)"); + + } catch (ResponseStatusException e) { } - - /** - * find channels using not modifier - */ - @Test - void findLackOfChannels() { - Property extraTestProperty = new Property(testProperties.get(0).getName(), "testOwner", "value2"); - Channel testChannel = new Channel("testChannel","testOwner",List.of(testProperties.get(0)),testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - Channel testChannel2 = new Channel("testChannel2","testOwner2",List.of(),List.of()); - Channel testChannel3 = new Channel("testChannel3","testOwner3",List.of(extraTestProperty),List.of()); - List testChannels = Arrays.asList(testChannel, testChannel1, testChannel2, testChannel3); - SearchResult foundChannelsResponse = null; - - List createdChannels = channelRepository.indexAll(testChannels); - SearchResult createdSearchResult = new SearchResult(createdChannels, 4); - cleanupTestChannels = testChannels; - - try { - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - searchParameters.set(testProperties.get(0).getName().toLowerCase() + "!", "*"); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(new SearchResult(List.of(createdChannels.get(2)), 1), foundChannelsResponse); - - } catch (ResponseStatusException e) { - Assertions.fail(e); - } - } - - /** - * find channels using case insensitive names searches - */ - @Test - void findChannelByCaseInsensitiveSearch() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel testChannel1 = new Channel("testChannel1","testOwner1",testProperties,testTags); - List testChannels = Arrays.asList(testChannel, testChannel1); - SearchResult foundChannelsResponse = null; - - List createdChannels = channelRepository.indexAll(testChannels); - SearchResult createdSearchResult = new SearchResult(createdChannels, 2); - cleanupTestChannels = Arrays.asList(testChannel,testChannel1); - - try { - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - - // Search for a single channel - searchParameters.set("~name", "testChannel"); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(new SearchResult(List.of(testChannel), 1), foundChannelsResponse, "Failed to find the based on channel name search (exact)"); - - searchParameters.set("~name", "testChannel".toLowerCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(new SearchResult(List.of(testChannel), 1), foundChannelsResponse, "Failed to find the based on channel name search (all lower case)"); - - searchParameters.set("~name", "testChannel".toUpperCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(new SearchResult(List.of(testChannel), 1), foundChannelsResponse, "Failed to find the based on channel name search (all upper case)"); - - // Search for multiple channels using case insensitive name searches - searchParameters.clear(); - searchParameters.set("~name", "testChannel*"); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on channel name search (exact)"); - - searchParameters.set("~name", "testChannel*".toLowerCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on channel name search (all lower case)"); - - searchParameters.set("~name", "testChannel*".toUpperCase()); - foundChannelsResponse = channelRepository.search(searchParameters); - Assertions.assertEquals(createdSearchResult, foundChannelsResponse, "Failed to find the based on channel name search (all upper case)"); - - - } catch (ResponseStatusException e) { - } + } + + /** delete a single tag */ + @Test + void deleteXmlTag() { + Channel testChannel = new Channel("testChannel", "testOwner", testProperties, testTags); + Channel createdChannel = channelRepository.index(testChannel); + cleanupTestChannels = Arrays.asList(testChannel); + + channelRepository.deleteById(createdChannel.getName()); + // verify the channel was deleted as expected + Assertions.assertNotEquals( + Optional.of(testChannel), + channelRepository.findById(testChannel.getName()), + "Failed to delete the channel"); + } + + /** + * Update a channel with 1. additional list of tags and properties 2. update the values of + * existing properties + */ + @Test + void updateChannelWithTagsAndProperties() { + Channel testChannel = new Channel(); + testChannel.setName("test-channel1"); + testChannel.setOwner("test-owner"); + cleanupTestChannels = Arrays.asList(testChannel); + + List props = createTestProperties(); + try { + testChannel.addProperty(testProperties.get(0)); + testChannel.addTag(testTags.get(0)); + Channel createdChannel = channelRepository.index(testChannel); + // verify the tag was created as expected + Assertions.assertEquals( + testChannel, + createdChannel, + "Failed to create the test channel with a list of tags & properties"); + // update the channel with new tags and properties + testChannel.setTags(testTags); + testChannel.setProperties(testProperties); + Channel updatedChannel = channelRepository.save(testChannel); + Assertions.assertEquals( + testChannel, + updatedChannel, + "Failed to create the test channel with a list of tags & properties"); + Assertions.assertTrue( + testChannel.getTags().containsAll(testTags), "Failed updated the channel with new tags"); + Assertions.assertTrue( + testChannel.getProperties().containsAll(testProperties), + "Failed updated the channel with new properties"); + // update the channel with new property values + testProperties.get(0).setValue("new-value0"); + testProperties.get(1).setValue("new-value1"); + testChannel.setProperties(testProperties); + Channel updatedValueChannel = channelRepository.save(testChannel); + Assertions.assertEquals( + testChannel, + updatedValueChannel, + "Failed to create the test channel with a list of tags & properties"); + Assertions.assertTrue( + testChannel.getTags().containsAll(testTags), "Failed updated the channel with new tags"); + Assertions.assertTrue( + testChannel.getProperties().containsAll(testProperties), + "Failed updated the channel with new properties"); + } catch (Exception e) { } - /** - * delete a single tag - */ - @Test - void deleteXmlTag() { - Channel testChannel = new Channel("testChannel","testOwner",testProperties,testTags); - Channel createdChannel = channelRepository.index(testChannel); - cleanupTestChannels = Arrays.asList(testChannel); - - channelRepository.deleteById(createdChannel.getName()); - // verify the channel was deleted as expected - Assertions.assertNotEquals(Optional.of(testChannel), channelRepository.findById(testChannel.getName()), "Failed to delete the channel"); - } - - /** - * Update a channel with - * 1. additional list of tags and properties - * 2. update the values of existing properties - */ - @Test - void updateChannelWithTagsAndProperties() { - Channel testChannel = new Channel(); - testChannel.setName("test-channel1"); - testChannel.setOwner("test-owner"); - cleanupTestChannels = Arrays.asList(testChannel); - - List props = createTestProperties(); - try { - testChannel.addProperty(testProperties.get(0)); - testChannel.addTag(testTags.get(0)); - Channel createdChannel = channelRepository.index(testChannel); - // verify the tag was created as expected - Assertions.assertEquals(testChannel, createdChannel, "Failed to create the test channel with a list of tags & properties"); - // update the channel with new tags and properties - testChannel.setTags(testTags); - testChannel.setProperties(testProperties); - Channel updatedChannel = channelRepository.save(testChannel); - Assertions.assertEquals(testChannel, updatedChannel, "Failed to create the test channel with a list of tags & properties"); - Assertions.assertTrue(testChannel.getTags().containsAll(testTags), "Failed updated the channel with new tags"); - Assertions.assertTrue(testChannel.getProperties().containsAll(testProperties), "Failed updated the channel with new properties"); - // update the channel with new property values - testProperties.get(0).setValue("new-value0"); - testProperties.get(1).setValue("new-value1"); - testChannel.setProperties(testProperties); - Channel updatedValueChannel = channelRepository.save(testChannel); - Assertions.assertEquals(testChannel, updatedValueChannel, "Failed to create the test channel with a list of tags & properties"); - Assertions.assertTrue(testChannel.getTags().containsAll(testTags), "Failed updated the channel with new tags"); - Assertions.assertTrue(testChannel.getProperties().containsAll(testProperties), "Failed updated the channel with new properties"); - } catch (Exception e) {} - props.forEach(testProperty -> { - propertyRepository.deleteById(testProperty.getName()); + props.forEach( + testProperty -> { + propertyRepository.deleteById(testProperty.getName()); }); + } + + /** + * Update a channel with partial objects, this is needed when you want to add a single tag or + * property + */ + @Test + void updateChannelWithPartialObjects() { + Channel testChannel = new Channel(); + testChannel.setName("testChannel"); + testChannel.setOwner("testOwner"); + cleanupTestChannels = Arrays.asList(testChannel); + + List props = createTestProperties(); + try { + testChannel.addTag(testTags.get(0)); + testChannel.addProperty(testProperties.get(4)); + Channel createdChannel = channelRepository.index(testChannel); + // verify the tag was created as expected + Assertions.assertEquals( + testChannel, + createdChannel, + "Failed to create the test channel with a list of tags & properties"); + // update the channel with new tags and properties provided via partial object + + Channel updateTestChannel = new Channel(); + updateTestChannel.setName("test-update-channel1"); + updateTestChannel.setOwner("test-owner"); + updateTestChannel.addTag(testTags.get(1)); + updateTestChannel.addProperty(testProperties.get(1)); + cleanupTestChannels.add(updateTestChannel); + + Channel updatedChannel = channelRepository.save(updateTestChannel); + + Channel expectedTestChannel = new Channel(); + expectedTestChannel.setName("test-update-channel1"); + expectedTestChannel.setOwner("test-owner"); + expectedTestChannel.addTag(testTags.get(0)); + expectedTestChannel.addTag(testTags.get(1)); + expectedTestChannel.addProperty(testProperties.get(0)); + expectedTestChannel.addProperty(testProperties.get(1)); + Assertions.assertEquals( + expectedTestChannel, + updatedChannel, + "Failed to create the test channel with a list of tags & properties"); + } catch (Exception e) { } - - /** - * Update a channel with partial objects, this is needed when you want to add a - * single tag or property - */ - @Test - void updateChannelWithPartialObjects() { - Channel testChannel = new Channel(); - testChannel.setName("testChannel"); - testChannel.setOwner("testOwner"); - cleanupTestChannels = Arrays.asList(testChannel); - - List props = createTestProperties(); - try { - testChannel.addTag(testTags.get(0)); - testChannel.addProperty(testProperties.get(4)); - Channel createdChannel = channelRepository.index(testChannel); - // verify the tag was created as expected - Assertions.assertEquals(testChannel, createdChannel, "Failed to create the test channel with a list of tags & properties"); - // update the channel with new tags and properties provided via partial object - - Channel updateTestChannel = new Channel(); - updateTestChannel.setName("test-update-channel1"); - updateTestChannel.setOwner("test-owner"); - updateTestChannel.addTag(testTags.get(1)); - updateTestChannel.addProperty(testProperties.get(1)); - cleanupTestChannels.add(updateTestChannel); - - Channel updatedChannel = channelRepository.save(updateTestChannel); - - Channel expectedTestChannel = new Channel(); - expectedTestChannel.setName("test-update-channel1"); - expectedTestChannel.setOwner("test-owner"); - expectedTestChannel.addTag(testTags.get(0)); - expectedTestChannel.addTag(testTags.get(1)); - expectedTestChannel.addProperty(testProperties.get(0)); - expectedTestChannel.addProperty(testProperties.get(1)); - Assertions.assertEquals(expectedTestChannel, updatedChannel, "Failed to create the test channel with a list of tags & properties"); - } catch (Exception e) {} - props.forEach(testProperty -> { - propertyRepository.deleteById(testProperty.getName()); + props.forEach( + testProperty -> { + propertyRepository.deleteById(testProperty.getName()); }); + } + + /** + * A utility class which will create the requested number of test properties named + * 'test-property#' + * + * @return list of created properties + */ + private List createTestProperties() { + List testProperties = new ArrayList(); + for (int i = 0; i < 2; i++) { + Property testProperty = new Property(); + testProperty.setName("test-property" + i); + testProperty.setOwner("test-owner"); + testProperty.setValue("test-property" + i + "-value"); + testProperties.add(testProperty); } - - - - /** - * A utility class which will create the requested number of test properties named 'test-property#' - * @return list of created properties - */ - private List createTestProperties(){ - List testProperties = new ArrayList(); - for (int i = 0; i < 2; i++) { - Property testProperty = new Property(); - testProperty.setName("test-property"+i); - testProperty.setOwner("test-owner"); - testProperty.setValue("test-property"+i+"-value"); - testProperties.add(testProperty); - } - try { - return Lists.newArrayList(propertyRepository.indexAll(testProperties)); - } catch (Exception e) { - propertyRepository.deleteAll(testProperties); - return Collections.emptyList(); - } - } - - - /** - * A utility class which will create the requested number of test tags named 'test-tag#' - * @return list of created tags - */ - private List createTestTags(int count){ - List testTags = new ArrayList(); - for (int i = 0; i < count; i++) { - Tag testTag = new Tag(); - testTag.setName("test-tag"+i); - testTag.setOwner("test-owner"); - testTags.add(testTag); - } - try { - return Lists.newArrayList(tagRepository.indexAll(testTags)); - } catch (Exception e) { - tagRepository.deleteAll(testTags); - return Collections.emptyList(); - } - + try { + return Lists.newArrayList(propertyRepository.indexAll(testProperties)); + } catch (Exception e) { + propertyRepository.deleteAll(testProperties); + return Collections.emptyList(); } - - // Helper operations to create and clean up the resources needed for successful - // testing of the channelRepository operations - - private final List testTags = Arrays.asList( - new Tag("testTag","testOwner"), - new Tag("testTag1","testOwner1")); - - private final List testUpdatedTags = Arrays.asList( - new Tag("testTag","updateTestOwner"), - new Tag("testTag1","updateTestOwner1")); - - private final List testProperties = Arrays.asList( - new Property("testProperty","testOwner","value"), - new Property("testProperty1","testOwner1","value")); - - private final List testUpdatedProperties = Arrays.asList( - new Property("testProperty","updateTestOwner","updatedValue"), - new Property("testProperty1","updateTestOwner1","updatedValue")); - - private List cleanupTestChannels = Collections.emptyList(); - - @BeforeEach - public void setup() { - tagRepository.indexAll(testTags); - propertyRepository.indexAll(testProperties); + } + + /** + * A utility class which will create the requested number of test tags named 'test-tag#' + * + * @return list of created tags + */ + private List createTestTags(int count) { + List testTags = new ArrayList(); + for (int i = 0; i < count; i++) { + Tag testTag = new Tag(); + testTag.setName("test-tag" + i); + testTag.setOwner("test-owner"); + testTags.add(testTag); } - - @AfterEach - public void cleanup() { - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); - propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); - } - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); + try { + return Lists.newArrayList(tagRepository.indexAll(testTags)); + } catch (Exception e) { + tagRepository.deleteAll(testTags); + return Collections.emptyList(); } -} \ No newline at end of file + } + + // Helper operations to create and clean up the resources needed for successful + // testing of the channelRepository operations + + private final List testTags = + Arrays.asList(new Tag("testTag", "testOwner"), new Tag("testTag1", "testOwner1")); + + private final List testUpdatedTags = + Arrays.asList(new Tag("testTag", "updateTestOwner"), new Tag("testTag1", "updateTestOwner1")); + + private final List testProperties = + Arrays.asList( + new Property("testProperty", "testOwner", "value"), + new Property("testProperty1", "testOwner1", "value")); + + private final List testUpdatedProperties = + Arrays.asList( + new Property("testProperty", "updateTestOwner", "updatedValue"), + new Property("testProperty1", "updateTestOwner1", "updatedValue")); + + private List cleanupTestChannels = Collections.emptyList(); + + @BeforeEach + public void setup() { + tagRepository.indexAll(testTags); + propertyRepository.indexAll(testProperties); + } + + @AfterEach + public void cleanup() { + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); + propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); + } + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/ChannelRepositorySearchIT.java b/src/test/java/org/phoebus/channelfinder/ChannelRepositorySearchIT.java index 22cf9515..8a127c47 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelRepositorySearchIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelRepositorySearchIT.java @@ -1,5 +1,14 @@ package org.phoebus.channelfinder; +import static java.lang.Math.min; +import static org.phoebus.channelfinder.example.PopulateService.valBucket; +import static org.phoebus.channelfinder.example.PopulateService.valBucketSize; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -16,155 +25,166 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static java.lang.Math.min; -import static org.phoebus.channelfinder.example.PopulateService.valBucket; -import static org.phoebus.channelfinder.example.PopulateService.valBucketSize; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelRepository.class) @TestPropertySource(locations = "classpath:application_test.properties") class ChannelRepositorySearchIT { - private static final Logger logger = Logger.getLogger(ChannelRepositorySearchIT.class.getName()); - - // Need at least 10 000 channels to test Elastic search beyond the 10 000 default result limit - // So needs to be a minimum of 7 - private final int CELLS = 100; - @Autowired - ChannelRepository channelRepository; - @Autowired - TagRepository tagRepository; - @Autowired - PropertyRepository propertyRepository; - @Autowired - ElasticConfig esService; - @Autowired - PopulateService populateService; - @Value("${elasticsearch.query.size:10000}") - int ELASTIC_LIMIT; - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } - - @BeforeEach - public void setup() throws InterruptedException { - populateService.cleanupDB(); - populateService.createDB(CELLS); - Thread.sleep(5000); - } - - @AfterEach - public void cleanup() throws InterruptedException { - populateService.cleanupDB(); - } - - /** - * Test searching for channel Note: the search tests are merged into a single test as an optimization. The - * population of the data cannot be performed in the @beforeClass since the springboot beans are not initialized - * hence the need to use @Before - */ - @Test - void searchTest() { - List channelNames = Arrays - .asList(populateService.getChannelList().toArray(new String[0])); - - MultiValueMap searchParameters = new LinkedMultiValueMap(); - //logger.log(Level.INFO, "Search for a single unique channel " + channelNames.get(0)); - - searchParameters.add("~name", channelNames.get(0)); - SearchResult result = channelRepository.search(searchParameters); - long countResult = channelRepository.count(searchParameters); - Assertions.assertEquals(1, result.count()); - Assertions.assertEquals(1, result.channels().size()); - Assertions.assertEquals(1, countResult); - Assertions.assertEquals(result.channels().get(0).getName(), channelNames.get(0)); - - logger.log(Level.INFO, "Search for all channels via wildcards"); - searchName(2,2, "BR:C001-BI:2{BLA}Pos:?-RB"); - - searchName(4, 4, "BR:C001-BI:?{BLA}Pos:*"); - - logger.log(Level.INFO, "Search for all 1000 channels"); - searchName(min(1000 * CELLS, ELASTIC_LIMIT), 1000 * CELLS, "SR*"); - - logger.log(Level.INFO, "Search for all 1000 SR channels and all 500 booster channels"); - long allCount = 1500 * CELLS; - long elasticDefaultCount = min(allCount, ELASTIC_LIMIT); - searchParameters.clear(); - searchParameters.add("~name", "SR*|BR*"); - assertSearchCount(elasticDefaultCount, (int) elasticDefaultCount, allCount, searchParameters); - - searchParameters.clear(); - searchParameters.add("~name", "SR*,BR*"); - assertSearchCount(elasticDefaultCount, (int) elasticDefaultCount, allCount, searchParameters); - - logger.log(Level.INFO, "Search for all 1000 SR channels and all 500 booster channels"); - searchParameters.clear(); - searchParameters.add("~name", "SR*|BR*"); - searchParameters.add("~track_total_hits", "true"); - assertSearchCount(allCount, (int) elasticDefaultCount, allCount, searchParameters); - - searchParameters.clear(); - searchParameters.add("~name", "SR*,BR*"); - searchParameters.add("~track_total_hits", "true"); - assertSearchCount(allCount, (int) elasticDefaultCount, allCount, searchParameters); - - logger.log(Level.INFO, "Search for channels based on a tag"); - for (long id = 1; id < valBucket.size(); id++) { - - for (int bucket_index = 0; bucket_index < valBucket.size(); bucket_index++) { - checkGroup(valBucketSize.get(bucket_index), "~tag", "group" + id + "_" + valBucket.get(bucket_index)); - checkGroup(valBucketSize.get(bucket_index), "group" + id, String.valueOf(valBucket.get(bucket_index))); - } - - } - - } - - private void searchName(int expectedChannels, int expectedQueryCount, String name) { - MultiValueMap searchParameters = new LinkedMultiValueMap<>(); - searchParameters.add("~name", name); - assertSearchCount(expectedChannels, expectedChannels, expectedQueryCount, searchParameters); - } - - private void assertSearchCount(long expectedResultCount, int expectedChannelsCount, long expectedQueryCount, MultiValueMap searchParameters) { - logger.log(Level.INFO, "Search for " + searchParameters + " expected " + expectedResultCount + " results " + expectedChannelsCount + " channels " + expectedQueryCount + " queries"); - // Act - SearchResult result = channelRepository.search(searchParameters); - - // Assert - Assertions.assertEquals(expectedResultCount, result.count()); - Assertions.assertEquals(expectedChannelsCount, result.channels().size()); - Assertions.assertEquals(expectedQueryCount, channelRepository.count(searchParameters)); - } - - private void checkGroup(int bucket, String key, String value) { - MultiValueMap searchParameters = new LinkedMultiValueMap(); - - searchParameters.add("~name", "SR*"); - searchParameters.add(key, value); - - SearchResult result = channelRepository.search(searchParameters); - Integer expectedCount = CELLS * bucket; - logger.log(Level.INFO, "Search for " + maptoString(searchParameters) + " expected " + expectedCount + " results"); - Assertions.assertEquals(min(expectedCount, ELASTIC_LIMIT), Integer.valueOf(result.channels().size()), "Search: " + maptoString(searchParameters)); - Assertions.assertEquals(expectedCount, Integer.valueOf((int) channelRepository.count(searchParameters))); - } - - private String maptoString(MultiValueMap searchParameters) { - StringBuffer sb = new StringBuffer(); - searchParameters.forEach((key, value) -> sb.append(key).append(" ").append(value)); - return sb.toString(); - } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); + private static final Logger logger = Logger.getLogger(ChannelRepositorySearchIT.class.getName()); + + // Need at least 10 000 channels to test Elastic search beyond the 10 000 default result limit + // So needs to be a minimum of 7 + private final int CELLS = 100; + @Autowired ChannelRepository channelRepository; + @Autowired TagRepository tagRepository; + @Autowired PropertyRepository propertyRepository; + @Autowired ElasticConfig esService; + @Autowired PopulateService populateService; + + @Value("${elasticsearch.query.size:10000}") + int ELASTIC_LIMIT; + + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } + + @BeforeEach + public void setup() throws InterruptedException { + populateService.cleanupDB(); + populateService.createDB(CELLS); + Thread.sleep(5000); + } + + @AfterEach + public void cleanup() throws InterruptedException { + populateService.cleanupDB(); + } + + /** + * Test searching for channel Note: the search tests are merged into a single test as an + * optimization. The population of the data cannot be performed in the @beforeClass since the + * springboot beans are not initialized hence the need to use @Before + */ + @Test + void searchTest() { + List channelNames = + Arrays.asList(populateService.getChannelList().toArray(new String[0])); + + MultiValueMap searchParameters = new LinkedMultiValueMap(); + // logger.log(Level.INFO, "Search for a single unique channel " + channelNames.get(0)); + + searchParameters.add("~name", channelNames.get(0)); + SearchResult result = channelRepository.search(searchParameters); + long countResult = channelRepository.count(searchParameters); + Assertions.assertEquals(1, result.count()); + Assertions.assertEquals(1, result.channels().size()); + Assertions.assertEquals(1, countResult); + Assertions.assertEquals(result.channels().get(0).getName(), channelNames.get(0)); + + logger.log(Level.INFO, "Search for all channels via wildcards"); + searchName(2, 2, "BR:C001-BI:2{BLA}Pos:?-RB"); + + searchName(4, 4, "BR:C001-BI:?{BLA}Pos:*"); + + logger.log(Level.INFO, "Search for all 1000 channels"); + searchName(min(1000 * CELLS, ELASTIC_LIMIT), 1000 * CELLS, "SR*"); + + logger.log(Level.INFO, "Search for all 1000 SR channels and all 500 booster channels"); + long allCount = 1500 * CELLS; + long elasticDefaultCount = min(allCount, ELASTIC_LIMIT); + searchParameters.clear(); + searchParameters.add("~name", "SR*|BR*"); + assertSearchCount(elasticDefaultCount, (int) elasticDefaultCount, allCount, searchParameters); + + searchParameters.clear(); + searchParameters.add("~name", "SR*,BR*"); + assertSearchCount(elasticDefaultCount, (int) elasticDefaultCount, allCount, searchParameters); + + logger.log(Level.INFO, "Search for all 1000 SR channels and all 500 booster channels"); + searchParameters.clear(); + searchParameters.add("~name", "SR*|BR*"); + searchParameters.add("~track_total_hits", "true"); + assertSearchCount(allCount, (int) elasticDefaultCount, allCount, searchParameters); + + searchParameters.clear(); + searchParameters.add("~name", "SR*,BR*"); + searchParameters.add("~track_total_hits", "true"); + assertSearchCount(allCount, (int) elasticDefaultCount, allCount, searchParameters); + + logger.log(Level.INFO, "Search for channels based on a tag"); + for (long id = 1; id < valBucket.size(); id++) { + + for (int bucket_index = 0; bucket_index < valBucket.size(); bucket_index++) { + checkGroup( + valBucketSize.get(bucket_index), + "~tag", + "group" + id + "_" + valBucket.get(bucket_index)); + checkGroup( + valBucketSize.get(bucket_index), + "group" + id, + String.valueOf(valBucket.get(bucket_index))); + } } + } + + private void searchName(int expectedChannels, int expectedQueryCount, String name) { + MultiValueMap searchParameters = new LinkedMultiValueMap<>(); + searchParameters.add("~name", name); + assertSearchCount(expectedChannels, expectedChannels, expectedQueryCount, searchParameters); + } + + private void assertSearchCount( + long expectedResultCount, + int expectedChannelsCount, + long expectedQueryCount, + MultiValueMap searchParameters) { + logger.log( + Level.INFO, + "Search for " + + searchParameters + + " expected " + + expectedResultCount + + " results " + + expectedChannelsCount + + " channels " + + expectedQueryCount + + " queries"); + // Act + SearchResult result = channelRepository.search(searchParameters); + + // Assert + Assertions.assertEquals(expectedResultCount, result.count()); + Assertions.assertEquals(expectedChannelsCount, result.channels().size()); + Assertions.assertEquals(expectedQueryCount, channelRepository.count(searchParameters)); + } + + private void checkGroup(int bucket, String key, String value) { + MultiValueMap searchParameters = new LinkedMultiValueMap(); + + searchParameters.add("~name", "SR*"); + searchParameters.add(key, value); + + SearchResult result = channelRepository.search(searchParameters); + Integer expectedCount = CELLS * bucket; + logger.log( + Level.INFO, + "Search for " + maptoString(searchParameters) + " expected " + expectedCount + " results"); + Assertions.assertEquals( + min(expectedCount, ELASTIC_LIMIT), + Integer.valueOf(result.channels().size()), + "Search: " + maptoString(searchParameters)); + Assertions.assertEquals( + expectedCount, Integer.valueOf((int) channelRepository.count(searchParameters))); + } + + private String maptoString(MultiValueMap searchParameters) { + StringBuffer sb = new StringBuffer(); + searchParameters.forEach((key, value) -> sb.append(key).append(" ").append(value)); + return sb.toString(); + } + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } } diff --git a/src/test/java/org/phoebus/channelfinder/ChannelScrollIT.java b/src/test/java/org/phoebus/channelfinder/ChannelScrollIT.java index c9e4f372..2e40fbc4 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelScrollIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelScrollIT.java @@ -1,5 +1,9 @@ package org.phoebus.channelfinder; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Random; import org.junit.jupiter.api.*; import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Scroll; @@ -10,169 +14,180 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Random; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelScroll.class) @TestPropertySource(value = "classpath:application_test.properties") class ChannelScrollIT { - - @Autowired - ChannelScroll channelScroll; - - @Autowired - ChannelRepository channelRepository; - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ElasticConfig esService; - - @Autowired - PopulateService populateService; - - @BeforeEach - public void setup() throws InterruptedException { - populateService.createDB(1); - Thread.sleep(10000); + @Autowired ChannelScroll channelScroll; + + @Autowired ChannelRepository channelRepository; + + @Autowired TagRepository tagRepository; + + @Autowired PropertyRepository propertyRepository; + + @Autowired ElasticConfig esService; + + @Autowired PopulateService populateService; + + @BeforeEach + public void setup() throws InterruptedException { + populateService.createDB(1); + Thread.sleep(10000); + } + + @AfterEach + public void cleanup() throws InterruptedException { + populateService.cleanupDB(); + } + + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + final List val_bucket = Arrays.asList(1, 2, 5, 10, 20, 50, 100, 200, 500); + + /** + * Test searching for channels based on name + * + * @throws InterruptedException + */ + @Test + void searchNameTest() throws InterruptedException { + List channelNames = + Arrays.asList( + populateService + .getChannelList() + .toArray(new String[populateService.getChannelList().size()])); + + MultiValueMap searchParameters = new LinkedMultiValueMap(); + // Search for a single unique channel + searchParameters.add("~name", channelNames.get(0)); + Scroll scrollResult = channelScroll.search(null, searchParameters); + List result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); } - - @AfterEach - public void cleanup() throws InterruptedException { - populateService.cleanupDB(); + Assertions.assertTrue( + result.size() == 1 && result.get(0).getName().equals(channelNames.get(0))); + + // Search for all channels via wildcards + searchParameters.clear(); + searchParameters.add("~name", "BR:C001-BI:2{BLA}Pos:?-RB"); + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); } - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); + Assertions.assertSame(2, result.size(), "Expected 2 but got " + result.size()); + + searchParameters.clear(); + searchParameters.add("~name", "BR:C001-BI:?{BLA}Pos:*"); + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); + Assertions.assertSame(4, result.size(), "Expected 4 but got " + result.size()); + + // Search for all 1000 channels + searchParameters.clear(); + searchParameters.add("~name", "SR*"); + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); } - - final List val_bucket = Arrays.asList(1, 2, 5, 10, 20, 50, 100, 200, 500); - - /** - * Test searching for channels based on name - * @throws InterruptedException - */ - @Test - void searchNameTest() throws InterruptedException { - List channelNames = Arrays - .asList(populateService.getChannelList().toArray(new String[populateService.getChannelList().size()])); - - MultiValueMap searchParameters = new LinkedMultiValueMap(); - // Search for a single unique channel - searchParameters.add("~name", channelNames.get(0)); - Scroll scrollResult = channelScroll.search(null,searchParameters); - List result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertTrue(result.size() == 1 && result.get(0).getName().equals(channelNames.get(0))); - - // Search for all channels via wildcards - searchParameters.clear(); - searchParameters.add("~name", "BR:C001-BI:2{BLA}Pos:?-RB"); - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertSame(2, result.size(), "Expected 2 but got " + result.size()); - - searchParameters.clear(); - searchParameters.add("~name", "BR:C001-BI:?{BLA}Pos:*"); - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertSame(4, result.size(), "Expected 4 but got " + result.size()); - - // Search for all 1000 channels - searchParameters.clear(); - searchParameters.add("~name", "SR*"); - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertEquals(1000, result.size(), "Expected 1000 but got " + result.size()); - - // Search for all 1000 SR channels and all 500 booster channels - searchParameters.clear(); - searchParameters.add("~name", "SR*|BR*"); - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); - - searchParameters.clear(); - searchParameters.add("~name", "SR*,BR*"); - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); - - // search for channels based on a tag - for (int i = 0; i < 5; i++) { - - long id = new Random().nextInt(10); - int index = new Random().nextInt(9); - searchParameters.clear(); - searchParameters.add("~name", "SR*"); - searchParameters.add("~tag", "group"+id+"_"+val_bucket.get(index)); - - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertEquals(val_bucket.get(index), Integer.valueOf(result.size()), "Search: "+ maptoString(searchParameters) +" Failed Expected "+val_bucket.get(index)+" but got " + result.size()); - } - - // search for channels based on a tag - for (int i = 0; i < 5; i++) { - - long id = new Random().nextInt(10); - int index = new Random().nextInt(9); - searchParameters.clear(); - searchParameters.add("~name", "SR*"); - searchParameters.add("group"+id, String.valueOf(val_bucket.get(index))); - - scrollResult = channelScroll.search(null,searchParameters); - result = scrollResult.getChannels(); - while(scrollResult.getChannels().size()==100) { - scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); - result.addAll(scrollResult.getChannels()); - } - Assertions.assertEquals(val_bucket.get(index), Integer.valueOf(result.size()), "Search: "+ maptoString(searchParameters) +" Failed Expected "+val_bucket.get(index)+" but got " + result.size()); - } + Assertions.assertEquals(1000, result.size(), "Expected 1000 but got " + result.size()); + + // Search for all 1000 SR channels and all 500 booster channels + searchParameters.clear(); + searchParameters.add("~name", "SR*|BR*"); + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); + } + Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); + + searchParameters.clear(); + searchParameters.add("~name", "SR*,BR*"); + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); + } + Assertions.assertEquals(1500, result.size(), "Expected 1500 but got " + result.size()); + + // search for channels based on a tag + for (int i = 0; i < 5; i++) { + + long id = new Random().nextInt(10); + int index = new Random().nextInt(9); + searchParameters.clear(); + searchParameters.add("~name", "SR*"); + searchParameters.add("~tag", "group" + id + "_" + val_bucket.get(index)); + + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); + } + Assertions.assertEquals( + val_bucket.get(index), + Integer.valueOf(result.size()), + "Search: " + + maptoString(searchParameters) + + " Failed Expected " + + val_bucket.get(index) + + " but got " + + result.size()); } - private String maptoString(MultiValueMap searchParameters) { - StringBuffer sb = new StringBuffer(); - searchParameters.forEach((key, value) -> sb.append(key).append(" ").append(value)); - return sb.toString(); + // search for channels based on a tag + for (int i = 0; i < 5; i++) { + + long id = new Random().nextInt(10); + int index = new Random().nextInt(9); + searchParameters.clear(); + searchParameters.add("~name", "SR*"); + searchParameters.add("group" + id, String.valueOf(val_bucket.get(index))); + + scrollResult = channelScroll.search(null, searchParameters); + result = scrollResult.getChannels(); + while (scrollResult.getChannels().size() == 100) { + scrollResult = channelScroll.search(scrollResult.getId(), searchParameters); + result.addAll(scrollResult.getChannels()); + } + Assertions.assertEquals( + val_bucket.get(index), + Integer.valueOf(result.size()), + "Search: " + + maptoString(searchParameters) + + " Failed Expected " + + val_bucket.get(index) + + " but got " + + result.size()); } + } + + private String maptoString(MultiValueMap searchParameters) { + StringBuffer sb = new StringBuffer(); + searchParameters.forEach((key, value) -> sb.append(key).append(" ").append(value)); + return sb.toString(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/ChannelScrollSearchIT.java b/src/test/java/org/phoebus/channelfinder/ChannelScrollSearchIT.java index 76e4f694..c97c2c44 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelScrollSearchIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelScrollSearchIT.java @@ -1,5 +1,8 @@ package org.phoebus.channelfinder; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -14,141 +17,185 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelScroll.class) @TestPropertySource(value = "classpath:application_test.properties") class ChannelScrollSearchIT { - private static final Logger logger = Logger.getLogger(ChannelScrollSearchIT.class.getName()); - - @Autowired - ChannelScroll channelScroll; - - @Autowired - TagRepository tagRepository; - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ElasticConfig esService; - @Autowired - PopulateService populateService; - - @BeforeEach - public void setup() throws InterruptedException { - populateService.createDB(1); - Thread.sleep(10000); - } - - @AfterEach - public void cleanup() throws InterruptedException { - populateService.cleanupDB(); - Thread.sleep(10000); + private static final Logger logger = Logger.getLogger(ChannelScrollSearchIT.class.getName()); + + @Autowired ChannelScroll channelScroll; + + @Autowired TagRepository tagRepository; + @Autowired PropertyRepository propertyRepository; + + @Autowired ElasticConfig esService; + @Autowired PopulateService populateService; + + @BeforeEach + public void setup() throws InterruptedException { + populateService.createDB(1); + Thread.sleep(10000); + } + + @AfterEach + public void cleanup() throws InterruptedException { + populateService.cleanupDB(); + Thread.sleep(10000); + } + + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + /** Test searching for channels based on name */ + @Test + void searchNameTest() { + + MultiValueMap searchParameters = new LinkedMultiValueMap(); + searchParameters.add("~name", "*"); + searchParameters.add("~size", "100"); + + long start = System.currentTimeMillis(); + Scroll scrollResult = channelScroll.query(searchParameters); + logger.log( + Level.INFO, + "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); + int totalResult = 0; + Double avg100 = 0.0; + + logger.log( + Level.INFO, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); + + while (scrollResult.getChannels().size() == 100) { + logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); + scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + logger.log( + Level.INFO, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); } - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); + logger.log(Level.INFO, "total result = " + totalResult); + + // Size = 1000 + logger.log(Level.INFO, "Rerun test with scroll size = 1000"); + searchParameters.add("~size", "1000"); + start = System.currentTimeMillis(); + scrollResult = channelScroll.query(searchParameters); + logger.log( + Level.INFO, + "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); + totalResult = 0; + Double avg1000 = 0.0; + + logger.log( + Level.INFO, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); + + while (scrollResult.getChannels().size() == 1000) { + logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); + scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + logger.log( + Level.INFO, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); + logger.log(Level.INFO, "total result = " + totalResult); + + // Size = 10000 + logger.log(Level.INFO, "Rerun test with scroll size = 10000"); + searchParameters.remove("~size"); + searchParameters.add("~size", "10000"); + start = System.currentTimeMillis(); + scrollResult = channelScroll.query(searchParameters); + logger.log( + Level.INFO, + "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); + totalResult = 0; + Double avg10000 = 0.0; + + logger.log( + Level.FINE, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); + + while (scrollResult.getChannels().size() == 10000) { + scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); + logger.log( + Level.FINE, + "Retrieved channels " + + totalResult + + " to " + + (totalResult + scrollResult.getChannels().size()) + + " in : " + + (System.currentTimeMillis() - start) + + "ms"); + avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; + totalResult += scrollResult.getChannels().size(); + start = System.currentTimeMillis(); } - - /** - * Test searching for channels based on name - */ - @Test - void searchNameTest() { - - MultiValueMap searchParameters = new LinkedMultiValueMap(); - searchParameters.add("~name", "*"); - searchParameters.add("~size", "100"); - - long start = System.currentTimeMillis(); - Scroll scrollResult = channelScroll.query(searchParameters); - logger.log(Level.INFO, "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); - int totalResult = 0; - Double avg100 = 0.0; - - logger.log(Level.INFO, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - - while (scrollResult.getChannels().size() == 100) { - logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - logger.log(Level.INFO, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg100 = (avg100 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - } - logger.log(Level.INFO, "total result = " + totalResult); - - // Size = 1000 - logger.log(Level.INFO, "Rerun test with scroll size = 1000"); - searchParameters.add("~size", "1000"); - start = System.currentTimeMillis(); - scrollResult = channelScroll.query(searchParameters); - logger.log(Level.INFO, "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); - totalResult = 0; - Double avg1000 = 0.0; - - logger.log(Level.INFO, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - - while (scrollResult.getChannels().size() == 1000) { - logger.log(Level.INFO, "Retireval id: " + scrollResult.getId()); - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - logger.log(Level.INFO, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg1000 = (avg1000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - } - logger.log(Level.INFO, "total result = " + totalResult); - - // Size = 10000 - logger.log(Level.INFO, "Rerun test with scroll size = 10000"); - searchParameters.remove("~size"); - searchParameters.add("~size", "10000"); - start = System.currentTimeMillis(); - scrollResult = channelScroll.query(searchParameters); - logger.log(Level.INFO, "Completed the first scroll request in : " + (System.currentTimeMillis() - start) + "ms"); - totalResult = 0; - Double avg10000 = 0.0; - - logger.log(Level.FINE, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - - while (scrollResult.getChannels().size() == 10000) { - scrollResult = channelScroll.query(scrollResult.getId(), searchParameters); - logger.log(Level.FINE, "Retrieved channels " + totalResult + " to " + (totalResult + scrollResult.getChannels().size()) - + " in : " + (System.currentTimeMillis() - start) + "ms"); - avg10000 = (avg10000 + (System.currentTimeMillis() - start)) / 2; - totalResult += scrollResult.getChannels().size(); - start = System.currentTimeMillis(); - } - logger.log(Level.INFO, "total result = " + totalResult); - - logger.log(Level.INFO, " compeleted scrolling db with \n" - + " size 100 in avg: " + avg100 + "\n" - + " size 1000 in avg: " + avg1000 + "\n" - + " size 10000 in avg: " + avg10000 + "\n"); - } - + logger.log(Level.INFO, "total result = " + totalResult); + + logger.log( + Level.INFO, + " compeleted scrolling db with \n" + + " size 100 in avg: " + + avg100 + + "\n" + + " size 1000 in avg: " + + avg1000 + + "\n" + + " size 10000 in avg: " + + avg10000 + + "\n"); + } } diff --git a/src/test/java/org/phoebus/channelfinder/ChannelValidationIT.java b/src/test/java/org/phoebus/channelfinder/ChannelValidationIT.java index 655ca2c8..fb298792 100644 --- a/src/test/java/org/phoebus/channelfinder/ChannelValidationIT.java +++ b/src/test/java/org/phoebus/channelfinder/ChannelValidationIT.java @@ -1,5 +1,10 @@ package org.phoebus.channelfinder; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.Arrays; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -14,183 +19,173 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(ChannelManager.class) @WithMockUser(roles = "CF-ADMINS") @TestPropertySource(value = "classpath:application_test.properties") class ChannelValidationIT { - @Autowired - ChannelManager channelManager; - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - ElasticConfig esService; - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - /** - * Attempt to Channel request with null name - */ - @Test - void validateXmlChannelRequestNullName() { - Channel testChannel1 = new Channel(null, "testOwner"); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - } + @Autowired ChannelManager channelManager; - /** - * Attempt to Channel request with empty name - */ - @Test - void validateXmlChannelRequestEmptyName() { - Channel testChannel1 = new Channel("", "testOwner"); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - } + @Autowired TagRepository tagRepository; - /** - * Attempt to Channel request with null owner - */ - @Test - void validateXmlChannelRequestNullOwner() { - Channel testChannel1 = new Channel("testChannel1", null); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - } + @Autowired PropertyRepository propertyRepository; - /** - * Attempt to Channel request with empty owner - */ - @Test - void validateXmlChannelRequestEmptyOwner() { - Channel testChannel1 = new Channel("testChannel1", ""); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - } + @Autowired ChannelRepository channelRepository; - /** - * Attempt to Channel request with a non existent tag - */ - @Test - void validateXmlChannelRequestFakeTag() { - // set up - Property prop = new Property("testProperty1","testOwner"); - propertyRepository.index(prop); - prop.setValue("value"); - - Channel testChannel1 = new Channel("testChannel1", "testOwner",Arrays.asList(prop),Arrays.asList(new Tag("Non-existent-tag"))); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - - // clean up - propertyRepository.deleteById(prop.getName()); - } + @Autowired ElasticConfig esService; - /** - * Attempt to Channel request with a non existent prop - */ - @Test - void validateXmlChannelRequestFakeProp() { - // set up - Tag tag = new Tag("testTag1","testOwner"); - tagRepository.index(tag); - - Channel testChannel1 = new Channel("testChannel1", "testOwner",Arrays.asList(new Property("Non-existent-property","Non-existent-property")),Arrays.asList(tag)); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - - // clean up - tagRepository.deleteById(tag.getName()); - } + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } - /** - * Attempt to Channel request with a null value prop - */ - @Test - void validateXmlChannelRequestNullProp() { - // set up - Tag tag = new Tag("testTag1","testOwner"); - tagRepository.index(tag); - Property prop = new Property("testProperty1","testOwner"); - propertyRepository.index(prop); - prop.setValue(null); - - Channel testChannel1 = new Channel("testChannel1", "testOwner",Arrays.asList(prop),Arrays.asList(tag)); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - - // clean up - tagRepository.deleteById(tag.getName()); - propertyRepository.deleteById(prop.getName()); - } - - /** - * Attempt to Channel request with an empty value prop - */ - @Test - void validateXmlChannelRequestEmptyProp() { - // set up - Tag tag = new Tag("testTag1","testOwner"); - tagRepository.index(tag); - Property prop = new Property("testProperty1","testOwner"); - propertyRepository.index(prop); - prop.setValue(""); - - Channel testChannel1 = new Channel("testChannel1", "testOwner",Arrays.asList(prop),Arrays.asList(tag)); - assertThrows(ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); - - // clean up - tagRepository.deleteById(tag.getName()); - propertyRepository.deleteById(prop.getName()); - } + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } - /** - * Attempt to Channel request with valid parameters - */ - @Test - void validateXmlChannelRequest() { - Channel testChannel1 = new Channel("testChannel1", "testOwner"); - try { - channelManager.validateChannelRequest(testChannel1); - Assertions.assertTrue(true); - } catch (Exception e) { - fail("Failed to validate with valid parameters"); - } - } - - /** - * Attempt to Channel request with valid parameters - */ - @Test - void validateXmlChannelRequest2() { - // set up - Tag tag = new Tag("testTag1","testOwner"); - tagRepository.index(tag); - Property prop = new Property("testProperty1","testOwner"); - propertyRepository.index(prop); - prop.setValue("value"); - - Channel testChannel1 = new Channel("testChannel1", "testOwner",Arrays.asList(prop),Arrays.asList(tag)); - channelManager.validateChannelRequest(testChannel1); - - // clean up - tagRepository.deleteById(tag.getName()); - propertyRepository.deleteById(prop.getName()); + /** Attempt to Channel request with null name */ + @Test + void validateXmlChannelRequestNullName() { + Channel testChannel1 = new Channel(null, "testOwner"); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + } + + /** Attempt to Channel request with empty name */ + @Test + void validateXmlChannelRequestEmptyName() { + Channel testChannel1 = new Channel("", "testOwner"); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + } + + /** Attempt to Channel request with null owner */ + @Test + void validateXmlChannelRequestNullOwner() { + Channel testChannel1 = new Channel("testChannel1", null); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + } + + /** Attempt to Channel request with empty owner */ + @Test + void validateXmlChannelRequestEmptyOwner() { + Channel testChannel1 = new Channel("testChannel1", ""); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + } + + /** Attempt to Channel request with a non existent tag */ + @Test + void validateXmlChannelRequestFakeTag() { + // set up + Property prop = new Property("testProperty1", "testOwner"); + propertyRepository.index(prop); + prop.setValue("value"); + + Channel testChannel1 = + new Channel( + "testChannel1", + "testOwner", + Arrays.asList(prop), + Arrays.asList(new Tag("Non-existent-tag"))); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + + // clean up + propertyRepository.deleteById(prop.getName()); + } + + /** Attempt to Channel request with a non existent prop */ + @Test + void validateXmlChannelRequestFakeProp() { + // set up + Tag tag = new Tag("testTag1", "testOwner"); + tagRepository.index(tag); + + Channel testChannel1 = + new Channel( + "testChannel1", + "testOwner", + Arrays.asList(new Property("Non-existent-property", "Non-existent-property")), + Arrays.asList(tag)); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + + // clean up + tagRepository.deleteById(tag.getName()); + } + + /** Attempt to Channel request with a null value prop */ + @Test + void validateXmlChannelRequestNullProp() { + // set up + Tag tag = new Tag("testTag1", "testOwner"); + tagRepository.index(tag); + Property prop = new Property("testProperty1", "testOwner"); + propertyRepository.index(prop); + prop.setValue(null); + + Channel testChannel1 = + new Channel("testChannel1", "testOwner", Arrays.asList(prop), Arrays.asList(tag)); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + + // clean up + tagRepository.deleteById(tag.getName()); + propertyRepository.deleteById(prop.getName()); + } + + /** Attempt to Channel request with an empty value prop */ + @Test + void validateXmlChannelRequestEmptyProp() { + // set up + Tag tag = new Tag("testTag1", "testOwner"); + tagRepository.index(tag); + Property prop = new Property("testProperty1", "testOwner"); + propertyRepository.index(prop); + prop.setValue(""); + + Channel testChannel1 = + new Channel("testChannel1", "testOwner", Arrays.asList(prop), Arrays.asList(tag)); + assertThrows( + ResponseStatusException.class, () -> channelManager.validateChannelRequest(testChannel1)); + + // clean up + tagRepository.deleteById(tag.getName()); + propertyRepository.deleteById(prop.getName()); + } + + /** Attempt to Channel request with valid parameters */ + @Test + void validateXmlChannelRequest() { + Channel testChannel1 = new Channel("testChannel1", "testOwner"); + try { + channelManager.validateChannelRequest(testChannel1); + Assertions.assertTrue(true); + } catch (Exception e) { + fail("Failed to validate with valid parameters"); } -} \ No newline at end of file + } + + /** Attempt to Channel request with valid parameters */ + @Test + void validateXmlChannelRequest2() { + // set up + Tag tag = new Tag("testTag1", "testOwner"); + tagRepository.index(tag); + Property prop = new Property("testProperty1", "testOwner"); + propertyRepository.index(prop); + prop.setValue("value"); + + Channel testChannel1 = + new Channel("testChannel1", "testOwner", Arrays.asList(prop), Arrays.asList(tag)); + channelManager.validateChannelRequest(testChannel1); + + // clean up + tagRepository.deleteById(tag.getName()); + propertyRepository.deleteById(prop.getName()); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/ElasticConfigIT.java b/src/test/java/org/phoebus/channelfinder/ElasticConfigIT.java index 93fd4851..b242a6ec 100644 --- a/src/test/java/org/phoebus/channelfinder/ElasticConfigIT.java +++ b/src/test/java/org/phoebus/channelfinder/ElasticConfigIT.java @@ -4,33 +4,36 @@ public class ElasticConfigIT { - /** - * Removes indexes created for the test - * - * @param elasticConfig Bean with configuration - * @throws IOException when request fails - */ - static void teardown(ElasticConfig elasticConfig) throws IOException { + /** + * Removes indexes created for the test + * + * @param elasticConfig Bean with configuration + * @throws IOException when request fails + */ + static void teardown(ElasticConfig elasticConfig) throws IOException { - String[] indexes = new String[] {elasticConfig.getES_CHANNEL_INDEX(), elasticConfig.getES_PROPERTY_INDEX(), elasticConfig.getES_TAG_INDEX()}; - for (String index: indexes) { - if (elasticConfig.getSearchClient().indices().exists(b -> b.index(index)).value()) { - elasticConfig.getSearchClient().indices().delete(b -> b.index(index)); - } - } - - } - - /** - * Makes sure the indexes are recreated before running a test - * This can happen if two tests share the same ElasticConfig bean and teardown is run at the end. - * For an example see PropertyManagerIT and PropertyValidationIT use the same @WebMvcTest annotation - * and then share the ElasticConfig Bean during test runs. - * - * @param elasticConfig Bean with configuration - */ - static void setUp(ElasticConfig elasticConfig) { - elasticConfig.elasticIndexValidation(elasticConfig.getSearchClient()); + String[] indexes = + new String[] { + elasticConfig.getES_CHANNEL_INDEX(), + elasticConfig.getES_PROPERTY_INDEX(), + elasticConfig.getES_TAG_INDEX() + }; + for (String index : indexes) { + if (elasticConfig.getSearchClient().indices().exists(b -> b.index(index)).value()) { + elasticConfig.getSearchClient().indices().delete(b -> b.index(index)); + } } + } + /** + * Makes sure the indexes are recreated before running a test This can happen if two tests share + * the same ElasticConfig bean and teardown is run at the end. For an example see + * PropertyManagerIT and PropertyValidationIT use the same @WebMvcTest annotation and then share + * the ElasticConfig Bean during test runs. + * + * @param elasticConfig Bean with configuration + */ + static void setUp(ElasticConfig elasticConfig) { + elasticConfig.elasticIndexValidation(elasticConfig.getSearchClient()); + } } diff --git a/src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java b/src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java index ed1150a2..c222dc23 100644 --- a/src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java +++ b/src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java @@ -1,5 +1,12 @@ package org.phoebus.channelfinder; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.IOException; +import java.util.List; +import java.util.stream.IntStream; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -18,14 +25,6 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import java.io.IOException; -import java.util.List; -import java.util.stream.IntStream; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = Application.class) @AutoConfigureMockMvc @@ -33,138 +32,137 @@ @TestPropertySource( locations = "classpath:application_test.properties", properties = { - "metrics.tags=testTag0, testTag1", - "metrics.properties=testProperty0: value0, value1; testProperty1: value0, !*", - "metrics.updateInterval=1" + "metrics.tags=testTag0, testTag1", + "metrics.properties=testProperty0: value0, value1; testProperty1: value0, !*", + "metrics.updateInterval=1" }) class MetricsServiceIT { - public static final String METRICS_ENDPOINT = "/actuator/metrics/"; - public static final String PROPERTY_NAME = "testProperty"; - public static final String OWNER = "testOwner"; - public static final String TAG_NAME = "testTag"; - public static final String METRICS_PARAM_KEY = "tag"; - public static final String PROPERTY_VALUE = "value"; - - - @Autowired - ChannelRepository channelRepository; - - @Autowired - TagRepository tagRepository; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ElasticConfig esService; - - @Autowired - PopulateService populateService; - - @Autowired - MetricsService metricsService; - - @Autowired - private MockMvc mockMvc; - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - - @AfterEach - public void cleanup() { - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); - propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); - } - - private void getAndExpectMetric(String paramValue, String endpoint, int expectedValue) throws Exception { - mockMvc.perform(get(METRICS_ENDPOINT + endpoint) - .param(METRICS_PARAM_KEY, paramValue)) - .andExpect(jsonPath("$.measurements[0].value").value(expectedValue)); - } - - private void getAndExpectMetricParent(String endpoint, int expectedValue) throws Exception { - mockMvc.perform(get(METRICS_ENDPOINT + endpoint)) - .andExpect(jsonPath("$.measurements[0].value").value(expectedValue)); - } - - @Test - void testGaugeMetrics() throws Exception { - mockMvc.perform(get(METRICS_ENDPOINT)).andExpect(status().is(200)); - getAndExpectMetricParent(MetricsService.CF_TOTAL_CHANNEL_COUNT, 0); - getAndExpectMetricParent(MetricsService.CF_PROPERTY_COUNT, 0); - getAndExpectMetricParent(MetricsService.CF_TAG_COUNT, 0); - - Channel testChannel = new Channel("testChannel", "testOwner"); - channelRepository.save(testChannel); - propertyRepository.saveAll(propertyList(3)); - tagRepository.saveAll(tagList(2)); - - getAndExpectMetricParent(MetricsService.CF_TOTAL_CHANNEL_COUNT, 1); - getAndExpectMetricParent(MetricsService.CF_PROPERTY_COUNT, 3); - getAndExpectMetricParent(MetricsService.CF_TAG_COUNT, 2); - } - - private List tagList(int count) { - return IntStream.range(0, count).mapToObj(i -> new Tag(TAG_NAME + i, OWNER)).toList(); - } - - private String tagParamValue(Tag tag) { - return String.format("tag:%s", tag.getName()); - } - - - private void getAndExpectTagMetric(Tag tag, int expectedValue) throws Exception { - getAndExpectMetric(tagParamValue(tag), MetricsService.CF_TAG_ON_CHANNELS_COUNT, expectedValue); - } - - @Test - void testTagMultiGaugeMetrics() throws Exception { - List testTags = tagList(3); - getAndExpectMetricParent(MetricsService.CF_TAG_ON_CHANNELS_COUNT, 0); - getAndExpectTagMetric(testTags.get(0), 0); - getAndExpectTagMetric(testTags.get(1), 0); - - tagRepository.saveAll(testTags); - - Channel testChannel = new Channel("testChannelTag", "testOwner", List.of(), testTags); - channelRepository.save(testChannel); - Channel testChannel1 = new Channel("testChannelTag1", "testOwner", List.of(), List.of(testTags.get(0))); - channelRepository.save(testChannel1); - - Thread.sleep(2000); // Update interval is 1 second - getAndExpectTagMetric(testTags.get(0), 2); - getAndExpectTagMetric(testTags.get(1), 1); - getAndExpectMetricParent(MetricsService.CF_TAG_ON_CHANNELS_COUNT, 3); - } - - private List propertyList(int count) { - return IntStream.range(0, count).mapToObj(i -> new Property(PROPERTY_NAME + i, OWNER)).toList(); - } - - private String propertyParamValue(Property property) { - return String.format("%s:%s", property.getName(), property.getValue()); - } - - private void getAndExpectPropertyMetric(Property property, int expectedValue) throws Exception { - getAndExpectMetric(propertyParamValue(property), MetricsService.CF_CHANNEL_COUNT, expectedValue); - } - - @Test - void testPropertyMultiGaugeMetrics() throws Exception { - List testProperties = propertyList(2); - - Channel testChannel = new Channel( + public static final String METRICS_ENDPOINT = "/actuator/metrics/"; + public static final String PROPERTY_NAME = "testProperty"; + public static final String OWNER = "testOwner"; + public static final String TAG_NAME = "testTag"; + public static final String METRICS_PARAM_KEY = "tag"; + public static final String PROPERTY_VALUE = "value"; + + @Autowired ChannelRepository channelRepository; + + @Autowired TagRepository tagRepository; + + @Autowired PropertyRepository propertyRepository; + + @Autowired ElasticConfig esService; + + @Autowired PopulateService populateService; + + @Autowired MetricsService metricsService; + + @Autowired private MockMvc mockMvc; + + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + @AfterEach + public void cleanup() { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); + propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); + } + + private void getAndExpectMetric(String paramValue, String endpoint, int expectedValue) + throws Exception { + mockMvc + .perform(get(METRICS_ENDPOINT + endpoint).param(METRICS_PARAM_KEY, paramValue)) + .andExpect(jsonPath("$.measurements[0].value").value(expectedValue)); + } + + private void getAndExpectMetricParent(String endpoint, int expectedValue) throws Exception { + mockMvc + .perform(get(METRICS_ENDPOINT + endpoint)) + .andExpect(jsonPath("$.measurements[0].value").value(expectedValue)); + } + + @Test + void testGaugeMetrics() throws Exception { + mockMvc.perform(get(METRICS_ENDPOINT)).andExpect(status().is(200)); + getAndExpectMetricParent(MetricsService.CF_TOTAL_CHANNEL_COUNT, 0); + getAndExpectMetricParent(MetricsService.CF_PROPERTY_COUNT, 0); + getAndExpectMetricParent(MetricsService.CF_TAG_COUNT, 0); + + Channel testChannel = new Channel("testChannel", "testOwner"); + channelRepository.save(testChannel); + propertyRepository.saveAll(propertyList(3)); + tagRepository.saveAll(tagList(2)); + + getAndExpectMetricParent(MetricsService.CF_TOTAL_CHANNEL_COUNT, 1); + getAndExpectMetricParent(MetricsService.CF_PROPERTY_COUNT, 3); + getAndExpectMetricParent(MetricsService.CF_TAG_COUNT, 2); + } + + private List tagList(int count) { + return IntStream.range(0, count).mapToObj(i -> new Tag(TAG_NAME + i, OWNER)).toList(); + } + + private String tagParamValue(Tag tag) { + return String.format("tag:%s", tag.getName()); + } + + private void getAndExpectTagMetric(Tag tag, int expectedValue) throws Exception { + getAndExpectMetric(tagParamValue(tag), MetricsService.CF_TAG_ON_CHANNELS_COUNT, expectedValue); + } + + @Test + void testTagMultiGaugeMetrics() throws Exception { + List testTags = tagList(3); + getAndExpectMetricParent(MetricsService.CF_TAG_ON_CHANNELS_COUNT, 0); + getAndExpectTagMetric(testTags.get(0), 0); + getAndExpectTagMetric(testTags.get(1), 0); + + tagRepository.saveAll(testTags); + + Channel testChannel = new Channel("testChannelTag", "testOwner", List.of(), testTags); + channelRepository.save(testChannel); + Channel testChannel1 = + new Channel("testChannelTag1", "testOwner", List.of(), List.of(testTags.get(0))); + channelRepository.save(testChannel1); + + Thread.sleep(2000); // Update interval is 1 second + getAndExpectTagMetric(testTags.get(0), 2); + getAndExpectTagMetric(testTags.get(1), 1); + getAndExpectMetricParent(MetricsService.CF_TAG_ON_CHANNELS_COUNT, 3); + } + + private List propertyList(int count) { + return IntStream.range(0, count).mapToObj(i -> new Property(PROPERTY_NAME + i, OWNER)).toList(); + } + + private String propertyParamValue(Property property) { + return String.format("%s:%s", property.getName(), property.getValue()); + } + + private void getAndExpectPropertyMetric(Property property, int expectedValue) throws Exception { + getAndExpectMetric( + propertyParamValue(property), MetricsService.CF_CHANNEL_COUNT, expectedValue); + } + + @Test + void testPropertyMultiGaugeMetrics() throws Exception { + List testProperties = propertyList(2); + + Channel testChannel = + new Channel( "testChannelProp", "testOwner", List.of( @@ -172,32 +170,34 @@ void testPropertyMultiGaugeMetrics() throws Exception { new Property(testProperties.get(1).getName(), OWNER, PROPERTY_VALUE + 0)), List.of()); - Channel testChannel1 = new Channel( + Channel testChannel1 = + new Channel( "testChannelProp1", "testOwner", List.of(new Property(testProperties.get(0).getName(), OWNER, PROPERTY_VALUE + 1)), List.of()); - getAndExpectMetricParent(MetricsService.CF_CHANNEL_COUNT, 0); - getAndExpectPropertyMetric(testChannel.getProperties().get(0), 0); - getAndExpectPropertyMetric(testChannel1.getProperties().get(0), 0); - - getAndExpectPropertyMetric(testChannel.getProperties().get(1), 0); - getAndExpectPropertyMetric(new Property(testProperties.get(1).getName(), OWNER, MetricsService.NOT_SET), 0); + getAndExpectMetricParent(MetricsService.CF_CHANNEL_COUNT, 0); + getAndExpectPropertyMetric(testChannel.getProperties().get(0), 0); + getAndExpectPropertyMetric(testChannel1.getProperties().get(0), 0); - propertyRepository.saveAll(testProperties); + getAndExpectPropertyMetric(testChannel.getProperties().get(1), 0); + getAndExpectPropertyMetric( + new Property(testProperties.get(1).getName(), OWNER, MetricsService.NOT_SET), 0); - channelRepository.save(testChannel); - channelRepository.save(testChannel1); + propertyRepository.saveAll(testProperties); - Thread.sleep(2000); // Update interval is 1 second + channelRepository.save(testChannel); + channelRepository.save(testChannel1); - getAndExpectMetricParent(MetricsService.CF_CHANNEL_COUNT, 2); - getAndExpectPropertyMetric(testChannel.getProperties().get(0), 1); - getAndExpectPropertyMetric(testChannel1.getProperties().get(0), 1); + Thread.sleep(2000); // Update interval is 1 second - getAndExpectPropertyMetric(testChannel.getProperties().get(1), 1); - getAndExpectPropertyMetric(new Property(testProperties.get(1).getName(), OWNER, MetricsService.NOT_SET), 1); + getAndExpectMetricParent(MetricsService.CF_CHANNEL_COUNT, 2); + getAndExpectPropertyMetric(testChannel.getProperties().get(0), 1); + getAndExpectPropertyMetric(testChannel1.getProperties().get(0), 1); - } + getAndExpectPropertyMetric(testChannel.getProperties().get(1), 1); + getAndExpectPropertyMetric( + new Property(testProperties.get(1).getName(), OWNER, MetricsService.NOT_SET), 1); + } } diff --git a/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java b/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java index 23a2db41..b9d45136 100644 --- a/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java +++ b/src/test/java/org/phoebus/channelfinder/MetricsServiceTest.java @@ -1,91 +1,92 @@ package org.phoebus.channelfinder; -import org.junit.jupiter.api.Test; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; class MetricsServiceTest { - - @Test - void testGenerateAllMultiValueMaps_example1() { - Map> properties = Map.of( + @Test + void testGenerateAllMultiValueMaps_example1() { + Map> properties = + Map.of( "a", List.of("b", "c"), - "d", List.of("e", "!*") - ); - List> allMaps = MetricsService.generateAllMultiValueMaps(properties); - - assertEquals(4, allMaps.size()); - - assertTrue(allMaps.contains(createMap("a", "b", "d", "e"))); - assertTrue(allMaps.contains(createMap("a", "c", "d", "e"))); - assertTrue(allMaps.contains(createMap("a", "b", "d!", "*"))); - assertTrue(allMaps.contains(createMap("a", "c", "d!", "*"))); - } - - @Test - void testGenerateAllMultiValueMaps_example2() { - Map> properties = Map.of( + "d", List.of("e", "!*")); + List> allMaps = + MetricsService.generateAllMultiValueMaps(properties); + + assertEquals(4, allMaps.size()); + + assertTrue(allMaps.contains(createMap("a", "b", "d", "e"))); + assertTrue(allMaps.contains(createMap("a", "c", "d", "e"))); + assertTrue(allMaps.contains(createMap("a", "b", "d!", "*"))); + assertTrue(allMaps.contains(createMap("a", "c", "d!", "*"))); + } + + @Test + void testGenerateAllMultiValueMaps_example2() { + Map> properties = + Map.of( "x", List.of("y", "z"), "p", List.of("q"), - "r", List.of("s", "t") - ); - List> allMaps = MetricsService.generateAllMultiValueMaps(properties); - - assertEquals(2 * 2, allMaps.size()); // 2 options (value or null) for each of 2 keys - - // Just a basic check, exhaustive check would be large - boolean foundExpectedCombination = false; - for (MultiValueMap map : allMaps) { - if (map.get("x").contains("y") && map.get("p").contains("q") && map.get("r").contains("s")) { - foundExpectedCombination = true; - break; - } - } - assertTrue(foundExpectedCombination); + "r", List.of("s", "t")); + List> allMaps = + MetricsService.generateAllMultiValueMaps(properties); + + assertEquals(2 * 2, allMaps.size()); // 2 options (value or null) for each of 2 keys + + // Just a basic check, exhaustive check would be large + boolean foundExpectedCombination = false; + for (MultiValueMap map : allMaps) { + if (map.get("x").contains("y") && map.get("p").contains("q") && map.get("r").contains("s")) { + foundExpectedCombination = true; + break; + } } - - @Test - void testGenerateAllMultiValueMaps_emptyList() { - Map> properties = Map.of( - "m", List.of() - ); - List> allMaps = MetricsService.generateAllMultiValueMaps(properties); - - assertEquals(0, allMaps.size()); // One with m=null, one with m implicitly null (not present) - } - - @Test - void testGenerateAllMultiValueMaps_emptyMap() { - Map> properties = Map.of(); - List> allMaps = MetricsService.generateAllMultiValueMaps(properties); - - assertEquals(1, allMaps.size()); + assertTrue(foundExpectedCombination); + } + + @Test + void testGenerateAllMultiValueMaps_emptyList() { + Map> properties = Map.of("m", List.of()); + List> allMaps = + MetricsService.generateAllMultiValueMaps(properties); + + assertEquals(0, allMaps.size()); // One with m=null, one with m implicitly null (not present) + } + + @Test + void testGenerateAllMultiValueMaps_emptyMap() { + Map> properties = Map.of(); + List> allMaps = + MetricsService.generateAllMultiValueMaps(properties); + + assertEquals(1, allMaps.size()); + } + + // Helper method to create a MultiValueMap for easier assertion + private MultiValueMap createMap( + String key1, String value1, String key2, String value2) { + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + if (key1 != null) { + map.add(key1, value1); } - - // Helper method to create a MultiValueMap for easier assertion - private MultiValueMap 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; + 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; + private MultiValueMap createMap(String key, String value) { + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + if (key != null) { + map.add(key, value); } + return map; + } } diff --git a/src/test/java/org/phoebus/channelfinder/PropertyManagerIT.java b/src/test/java/org/phoebus/channelfinder/PropertyManagerIT.java index 91d9e2ba..3a425320 100644 --- a/src/test/java/org/phoebus/channelfinder/PropertyManagerIT.java +++ b/src/test/java/org/phoebus/channelfinder/PropertyManagerIT.java @@ -1,6 +1,13 @@ package org.phoebus.channelfinder; +import static java.util.Collections.EMPTY_LIST; +import static org.junit.jupiter.api.Assertions.fail; + import com.google.common.collect.Iterables; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -19,739 +26,1366 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static java.util.Collections.EMPTY_LIST; -import static org.junit.jupiter.api.Assertions.fail; - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(PropertyManager.class) // TODO Somehow creating one @WithMockUser(roles = "CF-ADMINS") @TestPropertySource(value = "classpath:application_test.properties") class PropertyManagerIT { - @Autowired - PropertyManager propertyManager; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - ElasticConfig esService; - - @BeforeAll - void setupAll() { - ElasticConfigIT.setUp(esService); - } + @Autowired PropertyManager propertyManager; - // Helper operations to create and clean up the resources needed for successful - // testing of the PropertyManager operations + @Autowired PropertyRepository propertyRepository; - private final Channel testChannel0 = new Channel("testChannel0", "testOwner"); - private final Channel testChannel1 = new Channel("testChannel1", "testOwner"); - private final Channel testChannelX = new Channel("testChannelX", "testOwner"); + @Autowired ChannelRepository channelRepository; - private final List testChannels = Arrays.asList(testChannel0, - testChannel1, - testChannelX); + @Autowired ElasticConfig esService; - @BeforeEach - public void setup() { - channelRepository.indexAll(testChannels); - } + @BeforeAll + void setupAll() { + ElasticConfigIT.setUp(esService); + } - @AfterEach - public void cleanup() { - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); - } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - /** - * list all properties - */ - @Test - void listXmlProperties() { - Property testProperty0 = new Property("testProperty0","testOwner"); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),"value")),new ArrayList()))); - List testProperties = Arrays.asList(testProperty0,testProperty1); - - Iterable createdProperties = propertyManager.create(testProperties); - Iterable propertyList = propertyManager.list(); - for(Property property: createdProperties) { - property.setChannels(new ArrayList()); - } - // verify the properties were listed as expected - Assertions.assertEquals(createdProperties, propertyList, "Failed to list all properties"); - } + // Helper operations to create and clean up the resources needed for successful + // testing of the PropertyManager operations - /** - * read a single property - * test the "withChannels" flag - */ - @Test - void readXmlProperty() { - Property testProperty0 = new Property("testProperty0","testOwner"); - Property testProperty1 = new Property("testProperty1","testOwner"); - testProperty1.setChannels(Arrays.asList( - new Channel(testChannel0.getName(), - testChannel0.getOwner(), - Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),"value")), - new ArrayList()))); - - Property createdProperty0 = propertyManager.create(testProperty0.getName(),testProperty0); - Property createdProperty1 = propertyManager.create(testProperty1.getName(),testProperty1); - - // verify the created properties are read as expected - // retrieve the testProperty0 without channels - Property retrievedProperty = propertyManager.read(createdProperty0.getName(), false); - Assertions.assertEquals(createdProperty0, retrievedProperty, "Failed to read the property"); - // retrieve the testProperty0 with channels - retrievedProperty = propertyManager.read(createdProperty0.getName(), true); - Assertions.assertEquals(createdProperty0, retrievedProperty, "Failed to read the property w/ channels"); - - retrievedProperty = propertyManager.read(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); - // verify the property was read as expected - Assertions.assertEquals(createdProperty1, retrievedProperty, "Failed to read the property w/ channels"); - } + private final Channel testChannel0 = new Channel("testChannel0", "testOwner"); + private final Channel testChannel1 = new Channel("testChannel1", "testOwner"); + private final Channel testChannelX = new Channel("testChannelX", "testOwner"); - /** - * attempt to read a single non existent property - */ - @Test - void readNonExistingXmlProperty() { - // verify the property failed to be read, as expected - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.read("fakeProperty", false)); - } + private final List testChannels = + Arrays.asList(testChannel0, testChannel1, testChannelX); - /** - * attempt to read a single non existent property with channels - */ - @Test - void readNonExistingXmlProperty2() { - // verify the property failed to be read, as expected - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.read("fakeProperty", true)); - } + @BeforeEach + public void setup() { + channelRepository.indexAll(testChannels); + } - /** - * create a simple property - */ - @Test - void createXmlProperty() { - Property testProperty0 = new Property("testProperty0","testOwner"); - - // Create a simple property - Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); - Assertions.assertEquals(testProperty0, createdProperty, "Failed to create the property"); - - // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); - // // verify the property was created as expected - // assertEquals("Failed to create the property",testTag1,createdTag1); - - // Update the test property with a new owner - Property updatedTestProperty0 = new Property("testProperty0", "updateTestOwner"); - createdProperty = propertyManager.create(testProperty0.getName(), updatedTestProperty0); - Assertions.assertEquals(updatedTestProperty0, createdProperty, "Failed to create the property"); - } + @AfterEach + public void cleanup() { - /** - * Rename a simple property using create - */ - @Test - 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); - // 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 - Assertions.assertFalse(propertyRepository.existsById(testProperty0.getName()), "Failed to replace the old property"); - } + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + propertyRepository.findAll().forEach(p -> propertyRepository.deleteById(p.getName())); + } - /** - * create a single property with channels - */ - @Test - void createXmlProperty2() { - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - - Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - try { - Property foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); - Assertions.assertEquals(testProperty0WithChannels, foundProperty, "Failed to create the property w/ channels. Expected " + testProperty0WithChannels.toLog() + " found " - + foundProperty.toLog()); - } catch (Exception e) { - fail("Failed to create/find the property w/ channels"); - } - - // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); - // // verify the property was created as expected - // assertEquals("Failed to create the property",testTag1,createdTag1); - - // Update the test property with a new owner - Property updatedTestProperty0WithChannels = new Property("testProperty0WithChannels", "updateTestOwner"); - createdProperty = propertyManager.create(testProperty0WithChannels.getName(), updatedTestProperty0WithChannels); - try { - Property foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); - Assertions.assertEquals(updatedTestProperty0WithChannels, foundProperty, "Failed to create the property w/ channels. Expected " + updatedTestProperty0WithChannels.toLog() + " found " - + foundProperty.toLog()); - } catch (Exception e) { - fail("Failed to create/find the property w/ channels"); - } - } + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } - /** - * Rename a single property with channels using create - */ - @Test - void renameByCreateXmlProperty2() { - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property testProperty1WithChannels = new Property("testProperty1WithChannels","testOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value")),new ArrayList()))); - - // Create the testProperty0WithChannels - Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - // update the testProperty0WithChannels with testProperty1WithChannels - createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty1WithChannels); - try { - Property foundProperty = propertyRepository.findById(testProperty1WithChannels.getName(), true).get(); - Assertions.assertEquals(testProperty1WithChannels, foundProperty, "Failed to create the property w/ channels"); - } catch (Exception e) { - fail("Failed to create/find the property w/ channels"); - } - Assertions.assertFalse(propertyRepository.existsById(testProperty0WithChannels.getName()), "Failed to replace the old property"); - } - - /** - * create multiple properties - */ - @Test - void createXmlProperties() { - Property testProperty0 = new Property("testProperty0","testOwner"); - Property testProperty1 = new Property("testProperty1","testOwner"); - Property testProperty2 = new Property("testProperty2","testOwner"); - - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property testProperty1WithChannels = new Property("testProperty1WithChannels","testOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value")),new ArrayList()))); - Property testProperty2WithChannels = new Property("testProperty2WithChannels","testOwner"); - testProperty2WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty2WithChannels.getName(),testProperty2WithChannels.getOwner(),"value")),new ArrayList()))); - - List testProperties = Arrays.asList(testProperty0,testProperty1,testProperty2,testProperty0WithChannels,testProperty1WithChannels,testProperty2WithChannels); - - Iterable createdProperties = propertyManager.create(testProperties); - List foundProperties = new ArrayList(); - testProperties.forEach(prop -> foundProperties.add(propertyRepository.findById(prop.getName(),true).get())); - Assertions.assertTrue(foundProperties.containsAll(Arrays.asList(testProperty0, testProperty1, testProperty2)), "Failed to create the properties"); - Channel testChannel0With3Props = new Channel( + /** list all properties */ + @Test + void listXmlProperties() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( testChannel0.getName(), testChannel0.getOwner(), Arrays.asList( - new Property(testProperty0WithChannels.getName(), testProperty0WithChannels.getOwner(), "value"), - new Property(testProperty1WithChannels.getName(), testProperty0WithChannels.getOwner(), "value"), - new Property(testProperty2WithChannels.getName(), testProperty0WithChannels.getOwner(), "value")), - EMPTY_LIST); - Property expectedTestProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - expectedTestProperty0WithChannels.setChannels(Arrays.asList(testChannel0With3Props)); - Assertions.assertTrue(foundProperties.contains(expectedTestProperty0WithChannels)); + new Property(testProperty1.getName(), testProperty1.getOwner(), "value")), + new ArrayList()))); + List testProperties = Arrays.asList(testProperty0, testProperty1); + + Iterable createdProperties = propertyManager.create(testProperties); + Iterable propertyList = propertyManager.list(); + for (Property property : createdProperties) { + property.setChannels(new ArrayList()); } + // verify the properties were listed as expected + Assertions.assertEquals(createdProperties, propertyList, "Failed to list all properties"); + } + + /** read a single property test the "withChannels" flag */ + @Test + void readXmlProperty() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty1 = new Property("testProperty1", "testOwner"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property(testProperty1.getName(), testProperty1.getOwner(), "value")), + new ArrayList()))); + + Property createdProperty0 = propertyManager.create(testProperty0.getName(), testProperty0); + Property createdProperty1 = propertyManager.create(testProperty1.getName(), testProperty1); + + // verify the created properties are read as expected + // retrieve the testProperty0 without channels + Property retrievedProperty = propertyManager.read(createdProperty0.getName(), false); + Assertions.assertEquals(createdProperty0, retrievedProperty, "Failed to read the property"); + // retrieve the testProperty0 with channels + retrievedProperty = propertyManager.read(createdProperty0.getName(), true); + Assertions.assertEquals( + createdProperty0, retrievedProperty, "Failed to read the property w/ channels"); + + retrievedProperty = propertyManager.read(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); + // verify the property was read as expected + Assertions.assertEquals( + createdProperty1, retrievedProperty, "Failed to read the property w/ channels"); + } + + /** attempt to read a single non existent property */ + @Test + void readNonExistingXmlProperty() { + // verify the property failed to be read, as expected + Assertions.assertThrows( + ResponseStatusException.class, () -> propertyManager.read("fakeProperty", false)); + } + + /** attempt to read a single non existent property with channels */ + @Test + void readNonExistingXmlProperty2() { + // verify the property failed to be read, as expected + Assertions.assertThrows( + ResponseStatusException.class, () -> propertyManager.read("fakeProperty", true)); + } + + /** create a simple property */ + @Test + void createXmlProperty() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + + // Create a simple property + Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); + Assertions.assertEquals(testProperty0, createdProperty, "Failed to create the property"); + + // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); + // // verify the property was created as expected + // assertEquals("Failed to create the property",testTag1,createdTag1); + + // Update the test property with a new owner + Property updatedTestProperty0 = new Property("testProperty0", "updateTestOwner"); + createdProperty = propertyManager.create(testProperty0.getName(), updatedTestProperty0); + Assertions.assertEquals(updatedTestProperty0, createdProperty, "Failed to create the property"); + } + + /** Rename a simple property using create */ + @Test + 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); + // 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 + Assertions.assertFalse( + propertyRepository.existsById(testProperty0.getName()), + "Failed to replace the old property"); + } + + /** create a single property with channels */ + @Test + void createXmlProperty2() { + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); - /** - * create by overriding multiple properties - */ - @Test - void createXmlPropertiesWithOverride() { - Property testProperty0 = new Property("testProperty0","testOwner"); - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - List testProperties = Arrays.asList(testProperty0,testProperty0WithChannels); - - //Create a set of original properties to be overriden - propertyManager.create(testProperties); - // Now update the test properties - testProperty0.setOwner("testOwner-updated"); - testProperty0WithChannels.setOwner("testOwner-updated"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - - List updatedTestProperties = Arrays.asList(testProperty0,testProperty0WithChannels); - propertyManager.create(updatedTestProperties); - - // set owner back to original since it shouldn't change - testProperty0.setOwner("testOwner"); - testProperty0WithChannels.setOwner("testOwner"); - - List foundProperties = new ArrayList(); - testProperties.forEach(prop -> foundProperties.add(propertyRepository.findById(prop.getName(),true).get())); - // verify the properties were created as expected - Assertions.assertTrue(Iterables.elementsEqual(updatedTestProperties, foundProperties), "Failed to create the properties"); - - testChannels.get(1).setProperties(Arrays.asList(new Property("testProperty0WithChannels","testOwner","value"))); - MultiValueMap params = new LinkedMultiValueMap(); - params.add("testProperty0WithChannels", "*"); - // verify the property was removed from the old channels - Assertions.assertEquals(Arrays.asList(testChannels.get(1)), channelRepository.search(params).channels(), "Failed to delete the property from channels"); - } - - /** - * add a single property to a single channel - * @Todo fix this test after addsingle method is fixed - */ - @Test - void addSingleXmlProperty() { - Property testProperty0 = new Property("testProperty0", "testOwner"); - propertyRepository.index(testProperty0); - testProperty0.setValue("value"); - - propertyManager.addSingle(testProperty0.getName(), "testChannel0", testProperty0); - Assertions.assertTrue(channelRepository.findById("testChannel0").get().getProperties().stream().anyMatch(p -> { - return p.getName().equals(testProperty0.getName()); - }), "Failed to add property"); - } - - /** - * update a property - */ - @Test - void updateXmlProperty() { - // A test property with only name and owner - Property testProperty0 = new Property("testProperty0", "testOwner"); - // A test property with name, owner, and a single test channel with a copy of the property with a value and no channels - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - List testProperties = Arrays.asList(testProperty0,testProperty0WithChannels); - - // 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); - Assertions.assertEquals(testProperty0, returnedProperty, "Failed to update property " + testProperty0); - Assertions.assertEquals(testProperty0, propertyRepository.findById(testProperty0.getName()).get(), "Failed to update property " + testProperty0); - // 2. Test a property with channels - returnedProperty = propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, returnedProperty, "Failed to update property " + testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); - - // Update the property owner - testProperty0.setOwner("newTestOwner"); - returnedProperty = propertyManager.update(testProperty0.getName(), testProperty0); - Assertions.assertEquals(testProperty0, returnedProperty, "Failed to update property " + testProperty0); - Assertions.assertEquals(testProperty0, propertyRepository.findById(testProperty0.getName()).get(), "Failed to update property " + testProperty0); - testProperty0WithChannels.setOwner("newTestOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - returnedProperty = propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, returnedProperty, "Failed to update property " + testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); - } - - /** - * update a property's name and owner and value on its channels - */ - @Test - void updateXmlPropertyOnChan() { - // extra channel for this test - Channel testChannelX = new Channel("testChannelX","testOwner"); - channelRepository.index(testChannelX); - - // A test property with name, owner, and 2 test channels - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value0")), EMPTY_LIST), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"valueX")), EMPTY_LIST))); - // test property with different name, owner, and 1 different channel & 1 existing channel - Property testProperty1WithChannels = new Property("testProperty1WithChannels","updateTestOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value1")),EMPTY_LIST), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"newValueX")),EMPTY_LIST))); - + Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - // change name and owner on existing channel, add to new channel - propertyManager.update(testProperty0WithChannels.getName(), testProperty1WithChannels); - - Property expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner"); - expectedProperty.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value0")),EMPTY_LIST), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value1")),EMPTY_LIST), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"newValueX")),EMPTY_LIST))); - - // verify that the old property "testProperty0WithChannels" was replaced with the new "testProperty1WithChannels" and lists of channels were combined -// Optional foundProperty = propertyRepository.findById(testProperty1WithChannels.getName(), true); -// assertTrue("Failed to update the property", -// foundProperty.isPresent() && -// expectedProperty.equals(foundProperty)); - - // verify that the old property is no longer present - Assertions.assertFalse(propertyRepository.existsById(testProperty0WithChannels.getName()), "Failed to replace the old property"); - - expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "value0"); - // test property of old channel not in update - Assertions.assertTrue(channelRepository.findById(testChannel0.getName()).get().getProperties().contains(expectedProperty), "The property attached to the channel " + testChannels.get(0).toString() + " doesn't match the new property"); - - expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "value1"); - // test property of old channel and in update - Assertions.assertTrue(channelRepository.findById(testChannel1.getName()).get().getProperties().contains(expectedProperty), "The property attached to the channel " + testChannels.get(1).toString() + " doesn't match the new property"); - - expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "newValueX"); - // test property of new channel - Assertions.assertTrue(channelRepository.findById(testChannelX.getName()).get().getProperties().contains(expectedProperty), "The property attached to the channel " + testChannelX.toString() + " doesn't match the new property"); - - // clean extra channel - channelRepository.deleteById(testChannelX.getName()); - } - - /** - * Rename a property using update - */ - @Test - void renameByUpdateXmlProperty() { - Property testProperty0 = new Property("testProperty0","testOwner"); - Property testProperty1 = new Property("testProperty1","testOwner"); - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property testProperty1WithChannels = new Property("testProperty1WithChannels","testOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value")),new ArrayList()))); - - // Create the original properties - Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); - Property createdPropertyWithChannels = propertyManager.create(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); - - // verify that the old property "testProperty0" was replaced with the new "testProperty1" - try { - Property foundProperty = propertyRepository.findById(testProperty1.getName()).get(); - Assertions.assertEquals(testProperty1, foundProperty, "Failed to update the property"); - } catch (Exception e) { - fail("Failed to update/find the property"); - } - // verify that the old property is no longer present - Assertions.assertFalse(propertyRepository.existsById(testProperty0.getName()), "Failed to replace the old property"); - - // verify that the old property "testProperty0" was replaced with the new "testProperty1" - try { - Property foundProperty = propertyRepository.findById(testProperty1WithChannels.getName(), true).get(); - Assertions.assertEquals(testProperty1WithChannels, foundProperty, "Failed to update the property w/ channels"); - } catch (Exception e) { - fail("Failed to update/find the property w/ channels"); - } - // verify that the old property is no longer present - Assertions.assertFalse(propertyRepository.existsById(testProperty0WithChannels.getName()), "Failed to replace the old property"); - - // TODO add test for failure case + try { + Property foundProperty = + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); + Assertions.assertEquals( + testProperty0WithChannels, + foundProperty, + "Failed to create the property w/ channels. Expected " + + testProperty0WithChannels.toLog() + + " found " + + foundProperty.toLog()); + } catch (Exception e) { + fail("Failed to create/find the property w/ channels"); } - /** - * Update the channels/values associated with a property - * Existing property channels: none | update property channels: testChannel0 - * Resultant property channels: testChannel0 - */ - @Test - void updatePropertyTest1() { - // A test property with only name and owner - Property testProperty0 = new Property("testProperty0", "testOwner"); - propertyManager.create(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(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0.getName(),testProperty0.getOwner(),"value")),new ArrayList()))); - Property returnedTag = propertyManager.update(testProperty0.getName(), testProperty0); - Assertions.assertEquals(testProperty0, returnedTag, "Failed to update property " + testProperty0); - Assertions.assertEquals(testProperty0, propertyRepository.findById(testProperty0.getName(), true).get(), "Failed to update property " + testProperty0); + // Tag createdTag1 = tagManager.create("fakeTag", copy(testTag1)); + // // verify the property was created as expected + // assertEquals("Failed to create the property",testTag1,createdTag1); + + // Update the test property with a new owner + Property updatedTestProperty0WithChannels = + new Property("testProperty0WithChannels", "updateTestOwner"); + createdProperty = + propertyManager.create( + testProperty0WithChannels.getName(), updatedTestProperty0WithChannels); + try { + Property foundProperty = + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); + Assertions.assertEquals( + updatedTestProperty0WithChannels, + foundProperty, + "Failed to create the property w/ channels. Expected " + + updatedTestProperty0WithChannels.toLog() + + " found " + + foundProperty.toLog()); + } catch (Exception e) { + fail("Failed to create/find the property w/ channels"); } - - /** - * Update the channels/values associated with a property - * Existing property channels: testChannel0 | update property channels: testChannel1 - * Resultant property channels: testChannel0,testChannel1 - */ - @Test - void updatePropertyTest2() { - // A test property with testChannel0 - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - propertyManager.create(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 testChannel1 while leaving the existing channel unaffected. - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property returnedTag = propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, returnedTag, "Failed to update property " + testProperty0WithChannels); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); - } - - /** - * Update the channels/values associated with a property - * Existing property channels: testChannel0 | update property channels: testChannel0,testChannel1 - * Resultant property channels: testChannel0,testChannel1 - */ - @Test - void updatePropertyTest3() { - // A test property with testChannel0 - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); + } + + /** Rename a single property with channels using create */ + @Test + void renameByCreateXmlProperty2() { + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value")), + new ArrayList()))); + + // Create the testProperty0WithChannels + Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - // testProperty0WithChannels already has testChannel0, the update request (which repeats the testChannel0) - // should append the testChannel1 while leaving the existing channel unaffected. - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property returnedTag = propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, returnedTag, "Failed to update property " + testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); + // update the testProperty0WithChannels with testProperty1WithChannels + createdProperty = + propertyManager.create(testProperty0WithChannels.getName(), testProperty1WithChannels); + try { + Property foundProperty = + propertyRepository.findById(testProperty1WithChannels.getName(), true).get(); + Assertions.assertEquals( + testProperty1WithChannels, foundProperty, "Failed to create the property w/ channels"); + } catch (Exception e) { + fail("Failed to create/find the property w/ channels"); } - - /** - * Update the channels/values associated with a property - * Existing property channels: testChannel0,testChannel1 | update property channels: testChannel0,testChannel1 - * Resultant property channels: testChannel0,testChannel1 - */ - @Test - void updatePropertyTest4() { - // A test property with testChannel0,testChannel1 - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); + Assertions.assertFalse( + propertyRepository.existsById(testProperty0WithChannels.getName()), + "Failed to replace the old property"); + } + + /** create multiple properties */ + @Test + void createXmlProperties() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty1 = new Property("testProperty1", "testOwner"); + Property testProperty2 = new Property("testProperty2", "testOwner"); + + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property testProperty2WithChannels = new Property("testProperty2WithChannels", "testOwner"); + testProperty2WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty2WithChannels.getName(), + testProperty2WithChannels.getOwner(), + "value")), + new ArrayList()))); + + List testProperties = + Arrays.asList( + testProperty0, + testProperty1, + testProperty2, + testProperty0WithChannels, + testProperty1WithChannels, + testProperty2WithChannels); + + Iterable createdProperties = propertyManager.create(testProperties); + List foundProperties = new ArrayList(); + testProperties.forEach( + prop -> foundProperties.add(propertyRepository.findById(prop.getName(), true).get())); + Assertions.assertTrue( + foundProperties.containsAll(Arrays.asList(testProperty0, testProperty1, testProperty2)), + "Failed to create the properties"); + Channel testChannel0With3Props = + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value"), + new Property( + testProperty1WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value"), + new Property( + testProperty2WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + EMPTY_LIST); + Property expectedTestProperty0WithChannels = + new Property("testProperty0WithChannels", "testOwner"); + expectedTestProperty0WithChannels.setChannels(Arrays.asList(testChannel0With3Props)); + Assertions.assertTrue(foundProperties.contains(expectedTestProperty0WithChannels)); + } + + /** create by overriding multiple properties */ + @Test + void createXmlPropertiesWithOverride() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + List testProperties = Arrays.asList(testProperty0, testProperty0WithChannels); + + // Create a set of original properties to be overriden + propertyManager.create(testProperties); + // Now update the test properties + testProperty0.setOwner("testOwner-updated"); + testProperty0WithChannels.setOwner("testOwner-updated"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + + List updatedTestProperties = Arrays.asList(testProperty0, testProperty0WithChannels); + propertyManager.create(updatedTestProperties); + + // set owner back to original since it shouldn't change + testProperty0.setOwner("testOwner"); + testProperty0WithChannels.setOwner("testOwner"); + + List foundProperties = new ArrayList(); + testProperties.forEach( + prop -> foundProperties.add(propertyRepository.findById(prop.getName(), true).get())); + // verify the properties were created as expected + Assertions.assertTrue( + Iterables.elementsEqual(updatedTestProperties, foundProperties), + "Failed to create the properties"); + + testChannels + .get(1) + .setProperties( + Arrays.asList(new Property("testProperty0WithChannels", "testOwner", "value"))); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("testProperty0WithChannels", "*"); + // verify the property was removed from the old channels + Assertions.assertEquals( + Arrays.asList(testChannels.get(1)), + channelRepository.search(params).channels(), + "Failed to delete the property from channels"); + } + + /** + * add a single property to a single channel @Todo fix this test after addsingle method is fixed + */ + @Test + void addSingleXmlProperty() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + propertyRepository.index(testProperty0); + testProperty0.setValue("value"); + + propertyManager.addSingle(testProperty0.getName(), "testChannel0", testProperty0); + Assertions.assertTrue( + channelRepository.findById("testChannel0").get().getProperties().stream() + .anyMatch( + p -> { + return p.getName().equals(testProperty0.getName()); + }), + "Failed to add property"); + } + + /** update a property */ + @Test + void updateXmlProperty() { + // A test property with only name and owner + Property testProperty0 = new Property("testProperty0", "testOwner"); + // A test property with name, owner, and a single test channel with a copy of the property with + // a value and no channels + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + List testProperties = Arrays.asList(testProperty0, testProperty0WithChannels); + + // 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); + Assertions.assertEquals( + testProperty0, returnedProperty, "Failed to update property " + testProperty0); + Assertions.assertEquals( + testProperty0, + propertyRepository.findById(testProperty0.getName()).get(), + "Failed to update property " + testProperty0); + // 2. Test a property with channels + returnedProperty = + propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + returnedProperty, + "Failed to update property " + testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + + // Update the property owner + testProperty0.setOwner("newTestOwner"); + returnedProperty = propertyManager.update(testProperty0.getName(), testProperty0); + Assertions.assertEquals( + testProperty0, returnedProperty, "Failed to update property " + testProperty0); + Assertions.assertEquals( + testProperty0, + propertyRepository.findById(testProperty0.getName()).get(), + "Failed to update property " + testProperty0); + testProperty0WithChannels.setOwner("newTestOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + returnedProperty = + propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + returnedProperty, + "Failed to update property " + testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + } + + /** update a property's name and owner and value on its channels */ + @Test + void updateXmlPropertyOnChan() { + // extra channel for this test + Channel testChannelX = new Channel("testChannelX", "testOwner"); + channelRepository.index(testChannelX); + + // A test property with name, owner, and 2 test channels + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value0")), + EMPTY_LIST), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "valueX")), + EMPTY_LIST))); + // test property with different name, owner, and 1 different channel & 1 existing channel + Property testProperty1WithChannels = + new Property("testProperty1WithChannels", "updateTestOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value1")), + EMPTY_LIST), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "newValueX")), + EMPTY_LIST))); + + propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + // change name and owner on existing channel, add to new channel + propertyManager.update(testProperty0WithChannels.getName(), testProperty1WithChannels); + + Property expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner"); + expectedProperty.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value0")), + EMPTY_LIST), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value1")), + EMPTY_LIST), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "newValueX")), + EMPTY_LIST))); + + // verify that the old property "testProperty0WithChannels" was replaced with the new + // "testProperty1WithChannels" and lists of channels were combined + // Optional foundProperty = + // propertyRepository.findById(testProperty1WithChannels.getName(), true); + // assertTrue("Failed to update the property", + // foundProperty.isPresent() && + // expectedProperty.equals(foundProperty)); + + // verify that the old property is no longer present + Assertions.assertFalse( + propertyRepository.existsById(testProperty0WithChannels.getName()), + "Failed to replace the old property"); + + expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "value0"); + // test property of old channel not in update + Assertions.assertTrue( + channelRepository + .findById(testChannel0.getName()) + .get() + .getProperties() + .contains(expectedProperty), + "The property attached to the channel " + + testChannels.get(0).toString() + + " doesn't match the new property"); + + expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "value1"); + // test property of old channel and in update + Assertions.assertTrue( + channelRepository + .findById(testChannel1.getName()) + .get() + .getProperties() + .contains(expectedProperty), + "The property attached to the channel " + + testChannels.get(1).toString() + + " doesn't match the new property"); + + expectedProperty = new Property("testProperty1WithChannels", "updateTestOwner", "newValueX"); + // test property of new channel + Assertions.assertTrue( + channelRepository + .findById(testChannelX.getName()) + .get() + .getProperties() + .contains(expectedProperty), + "The property attached to the channel " + + testChannelX.toString() + + " doesn't match the new property"); + + // clean extra channel + channelRepository.deleteById(testChannelX.getName()); + } + + /** Rename a property using update */ + @Test + void renameByUpdateXmlProperty() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty1 = new Property("testProperty1", "testOwner"); + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value")), + new ArrayList()))); + + // Create the original properties + Property createdProperty = propertyManager.create(testProperty0.getName(), testProperty0); + Property createdPropertyWithChannels = propertyManager.create(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); - Assertions.assertEquals(testProperty0WithChannels, returnedTag, "Failed to update property " + testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); + // update the properties with new names, 0 -> 1 + Property updatedProperty = propertyManager.create(testProperty0.getName(), testProperty1); + Property updatedPropertyWithChannels = + propertyManager.create(testProperty0WithChannels.getName(), testProperty1WithChannels); + + // verify that the old property "testProperty0" was replaced with the new "testProperty1" + try { + Property foundProperty = propertyRepository.findById(testProperty1.getName()).get(); + Assertions.assertEquals(testProperty1, foundProperty, "Failed to update the property"); + } catch (Exception e) { + fail("Failed to update/find the property"); } - - /** - * Update the channels/values associated with a property - * Existing property channels: testChannel0,testChannel1 | update property channels: testChannel0 - * Resultant property channels: testChannel0,testChannel1 - */ - @Test - void updatePropertyTest5() { - // A test property with testChannel0,testChannel1 - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - propertyManager.create(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. - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Property returnedTag = propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); - Assertions.assertEquals(testProperty0WithChannels, returnedTag, "Failed to update property " + testProperty0WithChannels); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - Assertions.assertEquals(testProperty0WithChannels, propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), "Failed to update property " + testProperty0WithChannels); + // verify that the old property is no longer present + Assertions.assertFalse( + propertyRepository.existsById(testProperty0.getName()), + "Failed to replace the old property"); + + // verify that the old property "testProperty0" was replaced with the new "testProperty1" + try { + Property foundProperty = + propertyRepository.findById(testProperty1WithChannels.getName(), true).get(); + Assertions.assertEquals( + testProperty1WithChannels, foundProperty, "Failed to update the property w/ channels"); + } catch (Exception e) { + fail("Failed to update/find the property w/ channels"); } + // verify that the old property is no longer present + Assertions.assertFalse( + propertyRepository.existsById(testProperty0WithChannels.getName()), + "Failed to replace the old property"); + + // TODO add test for failure case + } + + /** + * Update the channels/values associated with a property Existing property channels: none | update + * property channels: testChannel0 Resultant property channels: testChannel0 + */ + @Test + void updatePropertyTest1() { + // A test property with only name and owner + Property testProperty0 = new Property("testProperty0", "testOwner"); + propertyManager.create(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( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property(testProperty0.getName(), testProperty0.getOwner(), "value")), + new ArrayList()))); + Property returnedTag = propertyManager.update(testProperty0.getName(), testProperty0); + Assertions.assertEquals( + testProperty0, returnedTag, "Failed to update property " + testProperty0); + Assertions.assertEquals( + testProperty0, + propertyRepository.findById(testProperty0.getName(), true).get(), + "Failed to update property " + testProperty0); + } + + /** + * Update the channels/values associated with a property Existing property channels: testChannel0 + * | update property channels: testChannel1 Resultant property channels: testChannel0,testChannel1 + */ + @Test + void updatePropertyTest2() { + // A test property with testChannel0 + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + propertyManager.create(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 + // testChannel1 while leaving the existing channel unaffected. + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property returnedTag = + propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + returnedTag, + "Failed to update property " + testProperty0WithChannels); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + } + + /** + * Update the channels/values associated with a property Existing property channels: testChannel0 + * | update property channels: testChannel0,testChannel1 Resultant property channels: + * testChannel0,testChannel1 + */ + @Test + void updatePropertyTest3() { + // A test property with testChannel0 + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + // testProperty0WithChannels already has testChannel0, the update request (which repeats the + // testChannel0) + // should append the testChannel1 while leaving the existing channel unaffected. + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property returnedTag = + propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + returnedTag, + "Failed to update property " + testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + } + + /** + * Update the channels/values associated with a property Existing property channels: + * testChannel0,testChannel1 | update property channels: testChannel0,testChannel1 Resultant + * property channels: testChannel0,testChannel1 + */ + @Test + void updatePropertyTest4() { + // A test property with testChannel0,testChannel1 + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + propertyManager.create(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); + Assertions.assertEquals( + testProperty0WithChannels, + returnedTag, + "Failed to update property " + testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + } + + /** + * Update the channels/values associated with a property Existing property channels: + * testChannel0,testChannel1 | update property channels: testChannel0 Resultant property channels: + * testChannel0,testChannel1 + */ + @Test + void updatePropertyTest5() { + // A test property with testChannel0,testChannel1 + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + propertyManager.create(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. + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Property returnedTag = + propertyManager.update(testProperty0WithChannels.getName(), testProperty0WithChannels); + Assertions.assertEquals( + testProperty0WithChannels, + returnedTag, + "Failed to update property " + testProperty0WithChannels); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + Assertions.assertEquals( + testProperty0WithChannels, + propertyRepository.findById(testProperty0WithChannels.getName(), true).get(), + "Failed to update property " + testProperty0WithChannels); + } + + /** Update the value of a property when channels have multiple properties */ + @Test + void updatePropertyWithChannelsTest() { + // A test property with testChannel0,testChannel1 + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + List.of( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "property0channel0")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + List.of( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "property0channel1")), + new ArrayList()))); + + Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + List.of( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "property1channel0")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + List.of( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "property1channel1")), + new ArrayList()))); + + propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); + propertyManager.create(testProperty1WithChannels.getName(), testProperty1WithChannels); + + Property newValueProperty = + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "newValueProperty"); + newValueProperty.setChannels( + List.of( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + List.of( + new Property( + newValueProperty.getName(), + newValueProperty.getOwner(), + "newValueProperty")), + new ArrayList()))); + propertyManager.update(newValueProperty.getName(), newValueProperty); + + List expected0Properties = + List.of( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "property0channel0"), + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "property1channel0")); + Assertions.assertEquals( + expected0Properties, + channelRepository.findById(testChannel0.getName()).get().getProperties()); + List expected1Properties = + List.of( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "property0channel1"), + new Property( + newValueProperty.getName(), newValueProperty.getOwner(), "newValueProperty")); + Assertions.assertEquals( + expected1Properties, + channelRepository.findById(testChannel1.getName()).get().getProperties()); + } + + /** + * Update multiple properties Update on non-existing properties should result in the creation of + * the properties + */ + @Test + void updateMultipleProperties() { + // A test property with only name and owner + Property testProperty0 = new Property("testProperty0", "testOwner"); + // A test property with name, owner, and test channels + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()), + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); + + propertyManager.update(Arrays.asList(testProperty0, testProperty0WithChannels)); + // Query ChannelFinder and verify updated channels and properties + Property foundProperty = propertyRepository.findById(testProperty0.getName(), true).get(); + Assertions.assertEquals( + testProperty0, foundProperty, "Failed to update property " + testProperty0); + foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); + Assertions.assertEquals( + testProperty0WithChannels, + foundProperty, + "Failed to update property " + testProperty0WithChannels); + } + + /** update properties' names and values and attempt to change owners on their channels */ + @Test + void updateMultipleXmlPropertiesOnChan() { + // extra channel for this test + Channel testChannelX = new Channel("testChannelX", "testOwner"); + channelRepository.index(testChannelX); + // 2 test properties with name, owner, and test channels + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value0")), + new ArrayList()), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "valueX")), + new ArrayList()))); + Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "value1")), + new ArrayList()), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "valueX")), + new ArrayList()))); + + propertyManager.create(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); + // change owners and add channels and change values + testProperty0WithChannels.setOwner("updateTestOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel1.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "newValue1")), + EMPTY_LIST), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "newValueX")), + EMPTY_LIST))); + testProperty1WithChannels.setOwner("updateTestOwner"); + testProperty1WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel1.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "newValue0")), + EMPTY_LIST), + new Channel( + testChannelX.getName(), + testChannelX.getOwner(), + Arrays.asList( + new Property( + testProperty1WithChannels.getName(), + testProperty1WithChannels.getOwner(), + "newValueX")), + EMPTY_LIST))); + + // update both properties + propertyManager.update(Arrays.asList(testProperty0WithChannels, testProperty1WithChannels)); + // create expected properties + + // verify that the properties were updated + // Optional foundProperty0 = + // propertyRepository.findById(testProperty0WithChannels.getName(), true); + // assertTrue("Failed to update the property" + expectedProperty0.toString(), + // foundProperty0.isPresent() && + // foundProperty0.get().getName().equalsIgnoreCase("testProperty0WithChannels") + // && + // foundProperty0.get().getChannels().); + // assertEquals("Failed to update the property" + expectedProperty0.toString(), + // expectedProperty0, foundProperty0); + // + // Optional foundProperty1 = + // propertyRepository.findById(testProperty1WithChannels.getName(), true); + // assertTrue("Failed to update the property" + expectedProperty1.toString(), + // expectedProperty1.equals(foundProperty1)); + + Property expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "value0"); + Property expectedProperty1 = + new Property("testProperty1WithChannels", "testOwner", "newValue0"); + List expectedProperties = Arrays.asList(expectedProperty0, expectedProperty1); + // test property of channel0 + Assertions.assertEquals( + expectedProperties, + channelRepository.findById(testChannel0.getName()).get().getProperties(), + "The property attached to the channel " + + testChannels.get(0).toString() + + " doesn't match the new property"); + + expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "newValue1"); + expectedProperty1 = new Property("testProperty1WithChannels", "testOwner", "value1"); + expectedProperties = Arrays.asList(expectedProperty0, expectedProperty1); + // test property of channel1 + Assertions.assertTrue( + channelRepository + .findById(testChannel1.getName()) + .get() + .getProperties() + .containsAll(expectedProperties), + "The property attached to the channel " + + testChannels.get(1).toString() + + " doesn't match the new property"); + + expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "newValueX"); + expectedProperty1 = new Property("testProperty1WithChannels", "testOwner", "newValueX"); + expectedProperties = Arrays.asList(expectedProperty0, expectedProperty1); + // test property of channelX + Assertions.assertTrue( + channelRepository + .findById(testChannelX.getName()) + .get() + .getProperties() + .containsAll(expectedProperties), + "The property attached to the channel " + + testChannelX.toString() + + " doesn't match the new property"); + + // clean extra channel + channelRepository.deleteById(testChannelX.getName()); + } + + /** delete a single property */ + @Test + void deleteXmlProperty() { + Property testProperty0 = new Property("testProperty0", "testOwner"); + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + EMPTY_LIST))); + List testProperties = Arrays.asList(testProperty0, testProperty0WithChannels); + + Iterable createdProperties = propertyManager.create(testProperties); + + propertyManager.remove(testProperty0.getName()); + // verify the property was deleted as expected + Assertions.assertFalse( + propertyRepository.existsById(testProperty0.getName()), "Failed to delete the property"); + + propertyManager.remove(testProperty0WithChannels.getName()); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("testProperty0WithChannels", "*"); + // verify the property was deleted and removed from all associated channels + Assertions.assertFalse( + propertyRepository.existsById(testProperty0WithChannels.getName()), + "Failed to delete the property"); + Assertions.assertEquals( + new ArrayList(), + channelRepository.search(params).channels(), + "Failed to delete the property from channels"); + } + + /** delete a single property from a single channel */ + @Test + void deleteXmlPropertyFromChannel() { + Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); + testProperty0WithChannels.setChannels( + Arrays.asList( + new Channel( + testChannel0.getName(), + testChannel0.getOwner(), + Arrays.asList( + new Property( + testProperty0WithChannels.getName(), + testProperty0WithChannels.getOwner(), + "value")), + new ArrayList()))); - /** - * Update the value of a property when channels have multiple properties - */ - @Test - void updatePropertyWithChannelsTest() { - // A test property with testChannel0,testChannel1 - Property testProperty0WithChannels = new Property("testProperty0WithChannels", "testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(), testChannel0.getOwner(), List.of(new Property(testProperty0WithChannels.getName(), testProperty0WithChannels.getOwner(), "property0channel0")), new ArrayList()), - new Channel(testChannel1.getName(), testChannel1.getOwner(), List.of(new Property(testProperty0WithChannels.getName(), testProperty0WithChannels.getOwner(), "property0channel1")), new ArrayList()))); - - Property testProperty1WithChannels = new Property("testProperty1WithChannels", "testOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(), testChannel0.getOwner(), List.of(new Property(testProperty1WithChannels.getName(), testProperty1WithChannels.getOwner(), "property1channel0")), new ArrayList()), - new Channel(testChannel1.getName(), testChannel1.getOwner(), List.of(new Property(testProperty1WithChannels.getName(), testProperty1WithChannels.getOwner(), "property1channel1")), new ArrayList()))); - + Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(), testProperty0WithChannels); - propertyManager.create(testProperty1WithChannels.getName(), testProperty1WithChannels); - - Property newValueProperty = new Property(testProperty1WithChannels.getName(), testProperty1WithChannels.getOwner(), "newValueProperty"); - newValueProperty.setChannels(List.of( - new Channel(testChannel1.getName(), testChannel1.getOwner(), List.of(new Property(newValueProperty.getName(), newValueProperty.getOwner(), "newValueProperty")), new ArrayList()))); - propertyManager.update(newValueProperty.getName(), newValueProperty); - - List expected0Properties = List.of(new Property(testProperty0WithChannels.getName(), testProperty0WithChannels.getOwner(), "property0channel0"), new Property(testProperty1WithChannels.getName(), testProperty1WithChannels.getOwner(), "property1channel0")); - Assertions.assertEquals(expected0Properties, channelRepository.findById(testChannel0.getName()).get().getProperties()); - List expected1Properties = List.of(new Property(testProperty0WithChannels.getName(), testProperty0WithChannels.getOwner(), "property0channel1"), new Property(newValueProperty.getName(), newValueProperty.getOwner(), "newValueProperty")); - Assertions.assertEquals(expected1Properties, channelRepository.findById(testChannel1.getName()).get().getProperties()); - } - - /** - * Update multiple properties - * Update on non-existing properties should result in the creation of the properties - */ - @Test - void updateMultipleProperties() { - // A test property with only name and owner - Property testProperty0 = new Property("testProperty0", "testOwner"); - // A test property with name, owner, and test channels - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()), - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - - propertyManager.update(Arrays.asList(testProperty0,testProperty0WithChannels)); - // Query ChannelFinder and verify updated channels and properties - Property foundProperty = propertyRepository.findById(testProperty0.getName(), true).get(); - Assertions.assertEquals(testProperty0, foundProperty, "Failed to update property " + testProperty0); - foundProperty = propertyRepository.findById(testProperty0WithChannels.getName(), true).get(); - Assertions.assertEquals(testProperty0WithChannels, foundProperty, "Failed to update property " + testProperty0WithChannels); - } - - /** - * update properties' names and values and attempt to change owners on their channels - */ - @Test - void updateMultipleXmlPropertiesOnChan() { - // extra channel for this test - Channel testChannelX = new Channel("testChannelX","testOwner"); - channelRepository.index(testChannelX); - // 2 test properties with name, owner, and test channels - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value0")),new ArrayList()), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"valueX")),new ArrayList()))); - Property testProperty1WithChannels = new Property("testProperty1WithChannels","testOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"value1")),new ArrayList()), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"valueX")),new ArrayList()))); - - propertyManager.create(Arrays.asList(testProperty0WithChannels,testProperty1WithChannels)); - // change owners and add channels and change values - testProperty0WithChannels.setOwner("updateTestOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel1.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"newValue1")),EMPTY_LIST), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"newValueX")),EMPTY_LIST))); - testProperty1WithChannels.setOwner("updateTestOwner"); - testProperty1WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel1.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"newValue0")),EMPTY_LIST), - new Channel(testChannelX.getName(),testChannelX.getOwner(),Arrays.asList(new Property(testProperty1WithChannels.getName(),testProperty1WithChannels.getOwner(),"newValueX")),EMPTY_LIST))); - - // update both properties - propertyManager.update(Arrays.asList(testProperty0WithChannels,testProperty1WithChannels)); - // create expected properties - - // verify that the properties were updated -// Optional foundProperty0 = propertyRepository.findById(testProperty0WithChannels.getName(), true); -// assertTrue("Failed to update the property" + expectedProperty0.toString(), -// foundProperty0.isPresent() && -// foundProperty0.get().getName().equalsIgnoreCase("testProperty0WithChannels") && -// foundProperty0.get().getChannels().); -// assertEquals("Failed to update the property" + expectedProperty0.toString(), -// expectedProperty0, foundProperty0); -// -// Optional foundProperty1 = propertyRepository.findById(testProperty1WithChannels.getName(), true); -// assertTrue("Failed to update the property" + expectedProperty1.toString(), -// expectedProperty1.equals(foundProperty1)); - - Property expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "value0"); - Property expectedProperty1 = new Property("testProperty1WithChannels", "testOwner", "newValue0"); - List expectedProperties = Arrays.asList(expectedProperty0,expectedProperty1); - // test property of channel0 - Assertions.assertEquals(expectedProperties, channelRepository.findById(testChannel0.getName()).get().getProperties(), "The property attached to the channel " + testChannels.get(0).toString() + " doesn't match the new property"); - - expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "newValue1"); - expectedProperty1 = new Property("testProperty1WithChannels", "testOwner", "value1"); - expectedProperties = Arrays.asList(expectedProperty0,expectedProperty1); - // test property of channel1 - Assertions.assertTrue(channelRepository.findById(testChannel1.getName()).get().getProperties().containsAll(expectedProperties), "The property attached to the channel " + testChannels.get(1).toString() + " doesn't match the new property"); - - expectedProperty0 = new Property("testProperty0WithChannels", "testOwner", "newValueX"); - expectedProperty1 = new Property("testProperty1WithChannels", "testOwner", "newValueX"); - expectedProperties = Arrays.asList(expectedProperty0,expectedProperty1); - // test property of channelX - Assertions.assertTrue(channelRepository.findById(testChannelX.getName()).get().getProperties().containsAll(expectedProperties), "The property attached to the channel " + testChannelX.toString() + " doesn't match the new property"); - - // clean extra channel - channelRepository.deleteById(testChannelX.getName()); - } - - /** - * delete a single property - */ - @Test - void deleteXmlProperty() { - Property testProperty0 = new Property("testProperty0", "testOwner"); - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),EMPTY_LIST))); - List testProperties = Arrays.asList(testProperty0,testProperty0WithChannels); - - Iterable createdProperties = propertyManager.create(testProperties); - - propertyManager.remove(testProperty0.getName()); - // verify the property was deleted as expected - Assertions.assertFalse( propertyRepository.existsById(testProperty0.getName()), "Failed to delete the property"); - - propertyManager.remove(testProperty0WithChannels.getName()); - MultiValueMap params = new LinkedMultiValueMap(); - params.add("testProperty0WithChannels", "*"); - // verify the property was deleted and removed from all associated channels - Assertions.assertFalse(propertyRepository.existsById(testProperty0WithChannels.getName()), "Failed to delete the property"); - Assertions.assertEquals(new ArrayList(), channelRepository.search(params).channels(), "Failed to delete the property from channels"); - } - - /** - * delete a single property from a single channel - */ - @Test - void deleteXmlPropertyFromChannel() { - Property testProperty0WithChannels = new Property("testProperty0WithChannels","testOwner"); - testProperty0WithChannels.setChannels(Arrays.asList( - new Channel(testChannel0.getName(),testChannel0.getOwner(),Arrays.asList(new Property(testProperty0WithChannels.getName(),testProperty0WithChannels.getOwner(),"value")),new ArrayList()))); - - Property createdProperty = propertyManager.create(testProperty0WithChannels.getName(),testProperty0WithChannels); - - propertyManager.removeSingle(testProperty0WithChannels.getName(),testChannel0.getName()); - // verify the property was only removed from the single test channel - Assertions.assertTrue(propertyRepository.existsById(testProperty0WithChannels.getName()), "Failed to not delete the property"); - - // Verify the property is removed from the testChannel0 - MultiValueMap searchParameters = new LinkedMultiValueMap(); - searchParameters.add("testProperty0WithChannels", "*"); - Assertions.assertFalse(channelRepository.search(searchParameters).channels().stream().anyMatch(ch -> { - return ch.getName().equals(testChannel0.getName()); - }), "Failed to delete the property from channel"); - } - -} \ No newline at end of file + propertyManager.removeSingle(testProperty0WithChannels.getName(), testChannel0.getName()); + // verify the property was only removed from the single test channel + Assertions.assertTrue( + propertyRepository.existsById(testProperty0WithChannels.getName()), + "Failed to not delete the property"); + + // Verify the property is removed from the testChannel0 + MultiValueMap searchParameters = new LinkedMultiValueMap(); + searchParameters.add("testProperty0WithChannels", "*"); + Assertions.assertFalse( + channelRepository.search(searchParameters).channels().stream() + .anyMatch( + ch -> { + return ch.getName().equals(testChannel0.getName()); + }), + "Failed to delete the property from channel"); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/PropertyRepositoryIT.java b/src/test/java/org/phoebus/channelfinder/PropertyRepositoryIT.java index 1ec8f4f9..38cd4f81 100644 --- a/src/test/java/org/phoebus/channelfinder/PropertyRepositoryIT.java +++ b/src/test/java/org/phoebus/channelfinder/PropertyRepositoryIT.java @@ -2,6 +2,12 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -17,244 +23,248 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.Set; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(PropertyRepository.class) @TestPropertySource(value = "classpath:application_test.properties") class PropertyRepositoryIT { - public static final String TEST_PROPERTY_NAME = "testProperty"; - - @Autowired - ElasticConfig esService; - - @Autowired - PropertyRepository propertyRepository; - - @Autowired - ChannelRepository channelRepository; - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - /** - * index a single property - */ - @Test - void indexXmlProperty() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - - Property createdProperty = propertyRepository.index(testProperty); - // verify the property was created as expected - Assertions.assertEquals(testProperty, createdProperty, "Failed to create the property"); - } - - /** - * index multiple properties - */ - @Test - void indexXmlProperties() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1,"testOwner1"); - List testProperties = Arrays.asList(testProperty, testProperty1); - - Iterable createdProperties = propertyRepository.indexAll(testProperties); - // verify the properties were created as expected - Assertions.assertTrue(Iterables.elementsEqual(testProperties, createdProperties), "Failed to create the list of properties"); - } - - /** - * save a single property - */ - @Test - void saveXmlProperty() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Property updateTestProperty = new Property(TEST_PROPERTY_NAME,"updateTestOwner"); - Property updateTestProperty1 = new Property(TEST_PROPERTY_NAME + 1,"updateTestOwner1"); - - Property createdProperty = propertyRepository.index(testProperty); - Property updatedTestProperty = propertyRepository.save(updateTestProperty); - // verify the property was updated as expected - Assertions.assertEquals(updateTestProperty, updatedTestProperty, "Failed to update the property with the same name"); - - Property updatedTestProperty1 = propertyRepository.save(TEST_PROPERTY_NAME,updateTestProperty1); - // verify the property was updated as expected - Assertions.assertEquals(updateTestProperty1, updatedTestProperty1, "Failed to update the property with a different name"); + public static final String TEST_PROPERTY_NAME = "testProperty"; + + @Autowired ElasticConfig esService; + + @Autowired PropertyRepository propertyRepository; + + @Autowired ChannelRepository channelRepository; + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + /** index a single property */ + @Test + void indexXmlProperty() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + + Property createdProperty = propertyRepository.index(testProperty); + // verify the property was created as expected + Assertions.assertEquals(testProperty, createdProperty, "Failed to create the property"); + } + + /** index multiple properties */ + @Test + void indexXmlProperties() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); + List testProperties = Arrays.asList(testProperty, testProperty1); + + Iterable createdProperties = propertyRepository.indexAll(testProperties); + // verify the properties were created as expected + Assertions.assertTrue( + Iterables.elementsEqual(testProperties, createdProperties), + "Failed to create the list of properties"); + } + + /** save a single property */ + @Test + void saveXmlProperty() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property updateTestProperty = new Property(TEST_PROPERTY_NAME, "updateTestOwner"); + Property updateTestProperty1 = new Property(TEST_PROPERTY_NAME + 1, "updateTestOwner1"); + + Property createdProperty = propertyRepository.index(testProperty); + Property updatedTestProperty = propertyRepository.save(updateTestProperty); + // verify the property was updated as expected + Assertions.assertEquals( + updateTestProperty, + updatedTestProperty, + "Failed to update the property with the same name"); + + Property updatedTestProperty1 = + propertyRepository.save(TEST_PROPERTY_NAME, updateTestProperty1); + // verify the property was updated as expected + Assertions.assertEquals( + updateTestProperty1, + updatedTestProperty1, + "Failed to update the property with a different name"); + } + + /** save multiple properties */ + @Test + void saveXmlProperties() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property updateTestProperty = new Property(TEST_PROPERTY_NAME, "updateTestOwner"); + Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); + Property updateTestProperty1 = new Property(TEST_PROPERTY_NAME + 1, "updateTestOwner1"); + List testProperties = Arrays.asList(testProperty, testProperty1); + List updateTestProperties = Arrays.asList(updateTestProperty, updateTestProperty1); + + Iterable createdProperties = propertyRepository.indexAll(testProperties); + Iterable updatedTestProperties = propertyRepository.saveAll(updateTestProperties); + // verify the properties were updated as expected + Assertions.assertTrue( + Iterables.elementsEqual(updateTestProperties, updatedTestProperties), + "Failed to update the properties"); + } + + /** find a single property */ + @Test + void findXmlProperty() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + + Optional notFoundProperty = propertyRepository.findById(testProperty.getName()); + // verify the property was not found as expected + Assertions.assertTrue( + notFoundProperty.isEmpty(), + "Found the property " + testProperty.getName() + " which should not exist."); + + Property createdProperty = propertyRepository.index(testProperty); + + Optional foundProperty = propertyRepository.findById(createdProperty.getName()); + // verify the property was found as expected + Assertions.assertEquals(createdProperty, foundProperty.get(), "Failed to find the property"); + + testProperty.setValue("test"); + Channel channel = + new Channel("testChannel", "testOwner", Arrays.asList(testProperty), new ArrayList()); + Channel createdChannel = channelRepository.index(channel); + + foundProperty = propertyRepository.findById(createdProperty.getName(), true); + createdProperty.setChannels(Arrays.asList(channel)); + // verify the property was found as expected + Property expectedProperty = new Property(createdProperty.getName(), createdProperty.getOwner()); + expectedProperty.setChannels(Arrays.asList(createdChannel)); + Assertions.assertEquals(expectedProperty, foundProperty.get(), "Failed to find the property"); + } + + /** check if a property exists */ + @Test + void testPropertyExists() { + + // check that non existing property returns false + Assertions.assertFalse( + propertyRepository.existsById("no-property"), + "Failed to check the non existing property :" + "no-property"); + + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Assertions.assertFalse( + propertyRepository.existsById(testProperty.getName()), + "Test property " + testProperty.getName() + " already exists"); + Property createdProperty = propertyRepository.index(testProperty); + + // verify the property exists as expected + Assertions.assertTrue( + propertyRepository.existsById(testProperty.getName()), + "Failed to check the existance of " + testProperty.getName()); + } + + /** find all properties */ + @Test + void findAllXmlProperties() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); + List testProperties = Arrays.asList(testProperty, testProperty1); + + try { + Set createdProperties = + Sets.newHashSet(propertyRepository.indexAll(testProperties)); + Set listedProperties = Sets.newHashSet(propertyRepository.findAll()); + // verify the properties were listed as expected + Assertions.assertEquals( + createdProperties, listedProperties, "Failed to list all created properties"); + } catch (Exception e) { + Assertions.fail(e); } - - /** - * save multiple properties - */ - @Test - void saveXmlProperties() { - Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); - Property updateTestProperty = new Property(TEST_PROPERTY_NAME, "updateTestOwner"); - Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); - Property updateTestProperty1 = new Property(TEST_PROPERTY_NAME + 1, "updateTestOwner1"); - List testProperties = Arrays.asList(testProperty, testProperty1); - List updateTestProperties = Arrays.asList(updateTestProperty, updateTestProperty1); - - Iterable createdProperties = propertyRepository.indexAll(testProperties); - Iterable updatedTestProperties = propertyRepository.saveAll(updateTestProperties); - // verify the properties were updated as expected - Assertions.assertTrue(Iterables.elementsEqual(updateTestProperties, updatedTestProperties), "Failed to update the properties"); + } + + /** find all properties */ + @Test + void countXmlProperties() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); + List testProperties = Arrays.asList(testProperty, testProperty1); + + try { + Set createdProperties = + Sets.newHashSet(propertyRepository.indexAll(testProperties)); + long listedPropertiesCount = propertyRepository.count(); + // verify the properties were listed as expected + Assertions.assertEquals( + createdProperties.size(), + listedPropertiesCount, + "Failed to count all created properties"); + } catch (Exception e) { + Assertions.fail(e); } - - /** - * find a single property - */ - @Test - void findXmlProperty() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - - Optional notFoundProperty = propertyRepository.findById(testProperty.getName()); - // verify the property was not found as expected - Assertions.assertTrue(notFoundProperty.isEmpty(), "Found the property " + testProperty.getName() + " which should not exist."); - - Property createdProperty = propertyRepository.index(testProperty); - - Optional foundProperty = propertyRepository.findById(createdProperty.getName()); - // verify the property was found as expected - Assertions.assertEquals(createdProperty, foundProperty.get(), "Failed to find the property"); - - testProperty.setValue("test"); - Channel channel = new Channel("testChannel","testOwner",Arrays.asList(testProperty),new ArrayList()); - Channel createdChannel = channelRepository.index(channel); - - foundProperty = propertyRepository.findById(createdProperty.getName(),true); - createdProperty.setChannels(Arrays.asList(channel)); - // verify the property was found as expected - Property expectedProperty = new Property(createdProperty.getName(), createdProperty.getOwner()); - expectedProperty.setChannels(Arrays.asList(createdChannel)); - Assertions.assertEquals(expectedProperty, foundProperty.get(), "Failed to find the property"); - + } + + /** find multiple properties */ + @Test + void findXmlProperties() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1, "testOwner1"); + List testProperties = Arrays.asList(testProperty, testProperty1); + List propertyNames = Arrays.asList(testProperty.getName(), testProperty1.getName()); + Iterable notFoundProperties = null; + Iterable foundProperties = null; + + try { + notFoundProperties = propertyRepository.findAllById(propertyNames); + } catch (ResponseStatusException e) { + } finally { + // verify the properties were not found as expected + Assertions.assertNotEquals(testProperties, notFoundProperties, "Found the properties"); } - /** - * check if a property exists - */ - @Test - void testPropertyExists() { - - // check that non existing property returns false - Assertions.assertFalse(propertyRepository.existsById("no-property"), "Failed to check the non existing property :" + "no-property"); - - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Assertions.assertFalse(propertyRepository.existsById(testProperty.getName()), "Test property " + testProperty.getName() + " already exists"); - Property createdProperty = propertyRepository.index(testProperty); - - // verify the property exists as expected - Assertions.assertTrue(propertyRepository.existsById(testProperty.getName()), "Failed to check the existance of " + testProperty.getName()); - } - - /** - * find all properties - */ - @Test - void findAllXmlProperties() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1,"testOwner1"); - List testProperties = Arrays.asList(testProperty, testProperty1); - - try { - Set createdProperties = Sets.newHashSet(propertyRepository.indexAll(testProperties)); - Set listedProperties = Sets.newHashSet(propertyRepository.findAll()); - // verify the properties were listed as expected - Assertions.assertEquals(createdProperties, listedProperties, "Failed to list all created properties"); - } catch (Exception e) { - Assertions.fail(e); - } - } - - /** - * find all properties - */ - @Test - void countXmlProperties() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1,"testOwner1"); - List testProperties = Arrays.asList(testProperty, testProperty1); - - try { - Set createdProperties = Sets.newHashSet(propertyRepository.indexAll(testProperties)); - long listedPropertiesCount = propertyRepository.count(); - // verify the properties were listed as expected - Assertions.assertEquals(createdProperties.size(), listedPropertiesCount, "Failed to count all created properties"); - } catch (Exception e) { - Assertions.fail(e); - } - } - - /** - * find multiple properties - */ - @Test - void findXmlProperties() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Property testProperty1 = new Property(TEST_PROPERTY_NAME + 1,"testOwner1"); - List testProperties = Arrays.asList(testProperty,testProperty1); - List propertyNames = Arrays.asList(testProperty.getName(),testProperty1.getName()); - Iterable notFoundProperties = null; - Iterable foundProperties = null; - - try { - notFoundProperties = propertyRepository.findAllById(propertyNames); - } catch (ResponseStatusException e) { - } finally { - // verify the properties were not found as expected - Assertions.assertNotEquals(testProperties, notFoundProperties, "Found the properties"); - } - - Iterable createdProperties = propertyRepository.indexAll(testProperties); - - try { - foundProperties = propertyRepository.findAllById(propertyNames); - } catch (ResponseStatusException e) { - } finally { - // verify the properties were found as expected - Assertions.assertEquals(createdProperties, foundProperties, "Failed to find the properties"); - } - } - - /** - * delete a single property - */ - @Test - void deleteXmlProperty() { - Property testProperty = new Property(TEST_PROPERTY_NAME,"testOwner"); - Optional notFoundProperty = propertyRepository.findById(testProperty.getName()); - Property createdProperty = propertyRepository.index(testProperty); - createdProperty.setValue("testValue"); - Channel channel = new Channel("testChannel","testOwner",Arrays.asList(createdProperty),null); - - Channel createdChannel = channelRepository.index(channel); - propertyRepository.deleteById(createdProperty.getName()); - // verify the property was deleted as expected - Assertions.assertNotEquals(testProperty, propertyRepository.findById(testProperty.getName()), "Failed to delete property"); - - Channel foundChannel = channelRepository.findById("testChannel").get(); - // verify the property was deleted from channels as expected - Assertions.assertTrue(foundChannel.getProperties().isEmpty(), "Failed to remove property from channel"); - - MultiValueMap params = new LinkedMultiValueMap(); - params.add(TEST_PROPERTY_NAME,"*"); - List chans = channelRepository.search(params).channels(); - // verify the property was deleted from channels as expected - Assertions.assertTrue(chans.isEmpty(), "Failed to remove property from channel"); - } + Iterable createdProperties = propertyRepository.indexAll(testProperties); - @AfterEach - public void cleanup() { - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - List.of(TEST_PROPERTY_NAME, TEST_PROPERTY_NAME + 1).forEach(pName ->propertyRepository.deleteById(pName)); + try { + foundProperties = propertyRepository.findAllById(propertyNames); + } catch (ResponseStatusException e) { + } finally { + // verify the properties were found as expected + Assertions.assertEquals(createdProperties, foundProperties, "Failed to find the properties"); } -} \ No newline at end of file + } + + /** delete a single property */ + @Test + void deleteXmlProperty() { + Property testProperty = new Property(TEST_PROPERTY_NAME, "testOwner"); + Optional notFoundProperty = propertyRepository.findById(testProperty.getName()); + Property createdProperty = propertyRepository.index(testProperty); + createdProperty.setValue("testValue"); + Channel channel = new Channel("testChannel", "testOwner", Arrays.asList(createdProperty), null); + + Channel createdChannel = channelRepository.index(channel); + propertyRepository.deleteById(createdProperty.getName()); + // verify the property was deleted as expected + Assertions.assertNotEquals( + testProperty, + propertyRepository.findById(testProperty.getName()), + "Failed to delete property"); + + Channel foundChannel = channelRepository.findById("testChannel").get(); + // verify the property was deleted from channels as expected + Assertions.assertTrue( + foundChannel.getProperties().isEmpty(), "Failed to remove property from channel"); + + MultiValueMap params = new LinkedMultiValueMap(); + params.add(TEST_PROPERTY_NAME, "*"); + List chans = channelRepository.search(params).channels(); + // verify the property was deleted from channels as expected + Assertions.assertTrue(chans.isEmpty(), "Failed to remove property from channel"); + } + + @AfterEach + public void cleanup() { + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + List.of(TEST_PROPERTY_NAME, TEST_PROPERTY_NAME + 1) + .forEach(pName -> propertyRepository.deleteById(pName)); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/PropertyValidationIT.java b/src/test/java/org/phoebus/channelfinder/PropertyValidationIT.java index fb4b59de..3c060f8b 100644 --- a/src/test/java/org/phoebus/channelfinder/PropertyValidationIT.java +++ b/src/test/java/org/phoebus/channelfinder/PropertyValidationIT.java @@ -1,5 +1,10 @@ package org.phoebus.channelfinder; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -13,176 +18,188 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.fail; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(PropertyManager.class) @WithMockUser(roles = "CF-ADMINS") @TestPropertySource(value = "classpath:application_test.properties") class PropertyValidationIT { - @Autowired - PropertyManager propertyManager; - - @Autowired - ChannelRepository channelRepository; - - @Autowired - ElasticConfig esService; - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - /** - * Attempt to Property request with null name - */ - @Test - void validateXmlPropertyRequestNullName() { - Property testProperty1 = new Property(null, "testOwner"); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with empty name - */ - @Test - void validateXmlPropertyRequestEmptyName() { - Property testProperty1 = new Property("", "testOwner"); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with null owner - */ - @Test - void validateXmlPropertyRequestNullOwner() { - Property testProperty1 = new Property("testProperty1", null); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with empty owner - */ - @Test - void validateXmlPropertyRequestEmptyOwner() { - Property testProperty1 = new Property("testProperty1", ""); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with a non existent channel - */ - @Test - void validateXmlPropertyRequestFakeChannel() { - Property testProperty1 = new Property("testProperty1", "testOwner"); - testProperty1.setChannels(Arrays.asList(new Channel("Non-existent-channel"))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with multiple non existent channels - */ - @Test - void validateXmlPropertyRequestFakeChannels() { - Property testProperty1 = new Property("testProperty1", "testOwner"); - testProperty1.setChannels( - Arrays.asList(new Channel("Non-existent-channel"), - new Channel("Non-existent-channel"))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - } - - /** - * Attempt to Property request with some existent(and valid) and some non existent channels - */ - @Test - void validateXmlPropertyRequestSomeFakeChannels() { - Channel chan = new Channel("testChannel0", "testOwner"); - channelRepository.index(chan); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(chan.getName(),chan.getOwner(),Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),"value")),new ArrayList()), - new Channel("Non-existent-channel"))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - channelRepository.deleteById("testChannel0"); + @Autowired PropertyManager propertyManager; + + @Autowired ChannelRepository channelRepository; + + @Autowired ElasticConfig esService; + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + /** Attempt to Property request with null name */ + @Test + void validateXmlPropertyRequestNullName() { + Property testProperty1 = new Property(null, "testOwner"); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with empty name */ + @Test + void validateXmlPropertyRequestEmptyName() { + Property testProperty1 = new Property("", "testOwner"); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with null owner */ + @Test + void validateXmlPropertyRequestNullOwner() { + Property testProperty1 = new Property("testProperty1", null); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with empty owner */ + @Test + void validateXmlPropertyRequestEmptyOwner() { + Property testProperty1 = new Property("testProperty1", ""); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with a non existent channel */ + @Test + void validateXmlPropertyRequestFakeChannel() { + Property testProperty1 = new Property("testProperty1", "testOwner"); + testProperty1.setChannels(Arrays.asList(new Channel("Non-existent-channel"))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with multiple non existent channels */ + @Test + void validateXmlPropertyRequestFakeChannels() { + Property testProperty1 = new Property("testProperty1", "testOwner"); + testProperty1.setChannels( + Arrays.asList(new Channel("Non-existent-channel"), new Channel("Non-existent-channel"))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + } + + /** Attempt to Property request with some existent(and valid) and some non existent channels */ + @Test + void validateXmlPropertyRequestSomeFakeChannels() { + Channel chan = new Channel("testChannel0", "testOwner"); + channelRepository.index(chan); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + chan.getName(), + chan.getOwner(), + Arrays.asList( + new Property(testProperty1.getName(), testProperty1.getOwner(), "value")), + new ArrayList()), + new Channel("Non-existent-channel"))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + channelRepository.deleteById("testChannel0"); + } + + /** Attempt to Property request with a channel that has no prop */ + @Test + void validateXmlPropertyRequestNoProp() { + Channel chan = new Channel("testChannel0", "testOwner"); + channelRepository.index(chan); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + chan.getName(), chan.getOwner(), new ArrayList(), new ArrayList()))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + channelRepository.deleteById("testChannel0"); + } + + /** Attempt to Property request with a null value */ + @Test + void validateXmlPropertyRequestNullValue() { + Channel chan = new Channel("testChannel0", "testOwner"); + channelRepository.index(chan); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + chan.getName(), + chan.getOwner(), + Arrays.asList( + new Property(testProperty1.getName(), testProperty1.getOwner(), null)), + new ArrayList()))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + channelRepository.deleteById("testChannel0"); + } + + /** Attempt to Property request with an empty value */ + @Test + void validateXmlPropertyRequestEmptyValue() { + Channel chan = new Channel("testChannel0", "testOwner"); + channelRepository.index(chan); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + chan.getName(), + chan.getOwner(), + Arrays.asList(new Property(testProperty1.getName(), testProperty1.getOwner(), "")), + new ArrayList()))); + Assertions.assertThrows( + ResponseStatusException.class, + () -> propertyManager.validatePropertyRequest(testProperty1)); + channelRepository.deleteById("testChannel0"); + } + + /** Attempt to Property request with valid parameters */ + @Test + void validateXmlPropertyRequest() { + Channel chan = new Channel("testChannel0", "testOwner"); + channelRepository.index(chan); + Property testProperty1 = new Property("testProperty1", "testOwner1"); + testProperty1.setChannels( + Arrays.asList( + new Channel( + chan.getName(), + chan.getOwner(), + Arrays.asList( + new Property(testProperty1.getName(), testProperty1.getOwner(), "value")), + new ArrayList()))); + try { + propertyManager.validatePropertyRequest(testProperty1); + Assertions.assertTrue(true); + } catch (Exception e) { + fail("Failed to validate with valid parameters"); } - - /** - * Attempt to Property request with a channel that has no prop - */ - @Test - void validateXmlPropertyRequestNoProp() { - Channel chan = new Channel("testChannel0", "testOwner"); - channelRepository.index(chan); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(chan.getName(),chan.getOwner(),new ArrayList(),new ArrayList()))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - channelRepository.deleteById("testChannel0"); - } - - /** - * Attempt to Property request with a null value - */ - @Test - void validateXmlPropertyRequestNullValue() { - Channel chan = new Channel("testChannel0", "testOwner"); - channelRepository.index(chan); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(chan.getName(),chan.getOwner(),Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),null)),new ArrayList()))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - channelRepository.deleteById("testChannel0"); - } - - /** - * Attempt to Property request with an empty value - */ - @Test - void validateXmlPropertyRequestEmptyValue() { - Channel chan = new Channel("testChannel0", "testOwner"); - channelRepository.index(chan); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(chan.getName(),chan.getOwner(),Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),"")),new ArrayList()))); - Assertions.assertThrows(ResponseStatusException.class, () -> propertyManager.validatePropertyRequest(testProperty1)); - channelRepository.deleteById("testChannel0"); - } - - /** - * Attempt to Property request with valid parameters - */ - @Test - void validateXmlPropertyRequest() { - Channel chan = new Channel("testChannel0", "testOwner"); - channelRepository.index(chan); - Property testProperty1 = new Property("testProperty1","testOwner1"); - testProperty1.setChannels(Arrays.asList( - new Channel(chan.getName(),chan.getOwner(),Arrays.asList(new Property(testProperty1.getName(),testProperty1.getOwner(),"value")),new ArrayList()))); - try { - propertyManager.validatePropertyRequest(testProperty1); - Assertions.assertTrue(true); - } catch (Exception e) { - fail("Failed to validate with valid parameters"); - } - channelRepository.deleteById("testChannel0"); - } - - /** - * Attempt to Property request with other valid parameters - */ - @Test - void validateXmlPropertyRequest2() { - Property testProperty1 = new Property("testProperty1","testOwner1"); - try { - propertyManager.validatePropertyRequest(testProperty1); - Assertions.assertTrue(true); - } catch (Exception e) { - fail("Failed to validate with valid parameters"); - } + channelRepository.deleteById("testChannel0"); + } + + /** Attempt to Property request with other valid parameters */ + @Test + void validateXmlPropertyRequest2() { + Property testProperty1 = new Property("testProperty1", "testOwner1"); + try { + propertyManager.validatePropertyRequest(testProperty1); + Assertions.assertTrue(true); + } catch (Exception e) { + fail("Failed to validate with valid parameters"); } -} \ No newline at end of file + } +} diff --git a/src/test/java/org/phoebus/channelfinder/TagManagerIT.java b/src/test/java/org/phoebus/channelfinder/TagManagerIT.java index 3e2526f7..5635b846 100644 --- a/src/test/java/org/phoebus/channelfinder/TagManagerIT.java +++ b/src/test/java/org/phoebus/channelfinder/TagManagerIT.java @@ -1,5 +1,15 @@ package org.phoebus.channelfinder; +import static java.util.Collections.EMPTY_LIST; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.logging.Logger; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -17,19 +27,6 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static java.util.Collections.EMPTY_LIST; -import static org.junit.jupiter.api.Assertions.fail; - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(TagManager.class) @WithMockUser(roles = "CF-ADMINS") @@ -37,668 +34,790 @@ @TestPropertySource(value = "classpath:application_test.properties") class TagManagerIT { - @Autowired - TagManager tagManager; + @Autowired TagManager tagManager; - @Autowired - TagRepository tagRepository; + @Autowired TagRepository tagRepository; - @Autowired - ChannelRepository channelRepository; + @Autowired ChannelRepository channelRepository; - @Autowired - ElasticConfig esService; - private static final Logger logger = Logger.getLogger(TagManagerIT.class.getName()); + @Autowired ElasticConfig esService; + private static final Logger logger = Logger.getLogger(TagManagerIT.class.getName()); - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } - /** - * list all tags - */ - @Test - void listXmlTags() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(testChannels()); - - List testTags = Arrays.asList(testTag0, testTag1); - Iterable createdTags = tagManager.create(testTags); - - Iterable tagList = tagManager.list(); - for (Tag tag : createdTags) { - tag.setChannels(new ArrayList<>()); - } - // verify the tags were listed as expected - Assertions.assertEquals(createdTags, tagList, "Failed to list all tags"); - } + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } - /** - * read a single tag - * test the "withChannels" flag - */ - @Test - void readXmlTag() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(testChannels()); - - Tag createdTag0 = tagManager.create(testTag0.getName(), testTag0); - Tag createdTag1 = tagManager.create(testTag1.getName(), testTag1); - - // verify the created tags are read as expected - // Retrieve the testTag0 without channels - Tag retrievedTag = tagManager.read(createdTag0.getName(), false); - Assertions.assertEquals(createdTag0, retrievedTag, "Failed to read the tag"); - // Retrieve the testTag0 with channels - retrievedTag = tagManager.read(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); - testTag1.setChannels(new ArrayList<>()); - Assertions.assertEquals(testTag1, retrievedTag, "Failed to read the tag"); - // Retrieve the testTag1 with channels - retrievedTag = tagManager.read(createdTag1.getName(), true); - Assertions.assertEquals(createdTag1, retrievedTag, "Failed to read the tag w/ channels"); - } + /** list all tags */ + @Test + void listXmlTags() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(testChannels()); - /** - * attempt to read a single non existent tag - */ - @Test - void readNonExistingXmlTag() { - // verify the tag failed to be read, as expected - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.read("fakeTag", false)); - } + List testTags = Arrays.asList(testTag0, testTag1); + Iterable createdTags = tagManager.create(testTags); - /** - * attempt to read a single non existent tag with channels - */ - @Test - void readNonExistingXmlTag2() { - // verify the tag failed to be read, as expected - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.read("fakeTag", true)); - } - - /** - * create a simple tag - */ - @Test - void createXmlTag() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - - // Create a simple tag - Tag createdTag = tagManager.create(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)); - Assertions.assertEquals(updatedTestTag0, createdTag, "Failed to create the tag"); - } - - /** - * Rename a simple tag using create - */ - @Test - 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); - // 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 - Assertions.assertFalse(tagRepository.existsById(testTag0.getName()), "Failed to replace the old tag"); - } - - /** - * Create a single tag with channels - */ - @Test - void createXmlTag2() { - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(testChannels()); - - tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); - try { - Tag foundTag = tagRepository.findById(testTag0WithChannels.getName(), true).get(); - Tag expectedTag = new Tag("testTag0WithChannels", "testOwner"); - expectedTag.setChannels(Arrays.asList( - new Channel("testChannel0", "testOwner", EMPTY_LIST, List.of(new Tag("testTag0WithChannels", "testOwner"))), - new Channel("testChannel1", "testOwner", EMPTY_LIST, List.of(new Tag("testTag0WithChannels", "testOwner"))))); - Assertions.assertEquals(expectedTag, foundTag, "Failed to create the tag w/ channels. Expected " + expectedTag.toLog() + " found " - + foundTag.toLog()); - - } catch (Exception e) { - fail("Failed to create/find the tag w/ channels due to exception " + e.getMessage()); - } - - Tag updatedTestTag0WithChannels = new Tag("testTag0WithChannels", "updateTestOwner"); - - tagManager.create(testTag0WithChannels.getName(), copy(updatedTestTag0WithChannels)); - try { - Tag foundTag = tagRepository.findById(updatedTestTag0WithChannels.getName(), true).get(); - // verify the tag was created as expected - Assertions.assertTrue(tagCompare(updatedTestTag0WithChannels, foundTag), "Failed to create the tag w/ channels"); - } catch (Exception e) { - fail("Failed to create/find the tag w/ channels"); - } - } - - /** - * Rename a single tag with channels using create - */ - @Test - void renameByCreateXmlTag2() { - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(testChannels()); - Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); - testTag1WithChannels.setChannels(testChannels()); - - // Create the testTag0WithChannels - tagManager.create(testTag0WithChannels.getName(), copy(testTag0WithChannels)); - // update the testTag0WithChannels with testTag1WithChannels - tagManager.create(testTag0WithChannels.getName(), copy(testTag1WithChannels)); - try { - Tag foundTag = tagRepository.findById(testTag1WithChannels.getName(), true).get(); - Assertions.assertFalse(tagRepository.existsById("testTag0WithChannels"), "Failed to rename the Tag - the old tag still exists"); - Assertions.assertTrue(tagRepository.existsById("testTag1WithChannels"), "Failed to rename the Tag - the new tag does not exists"); - Assertions.assertSame(2, tagRepository.findById("testTag1WithChannels", true).get().getChannels().size(), "Failed to rename the Tag - the new tag does have the channels"); - } catch (Exception e) { - fail("Failed to create/find the tag w/ channels"); - } - Assertions.assertFalse(tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); + Iterable tagList = tagManager.list(); + for (Tag tag : createdTags) { + tag.setChannels(new ArrayList<>()); } - - /** - * create multiple tags - */ - @Test - void createXmlTags() { - - Tag testTag0 = new Tag("testTag0", "testOwner"); - Tag testTag1 = new Tag("testTag1", "testOwner"); - Tag testTag2 = new Tag("testTag2", "testOwner"); - - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(testChannels()); - Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); - testTag1WithChannels.setChannels(testChannels()); - Tag testTag2WithChannels = new Tag("testTag2WithChannels", "testOwner"); - testTag2WithChannels.setChannels(testChannels()); - - List testTags = Arrays.asList(testTag0, testTag1, testTag2, testTag0WithChannels, testTag1WithChannels, testTag2WithChannels); - - tagManager.create(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 "); - Assertions.assertTrue(foundTags.contains(testTag1), "Failed to create the tags testTag1 "); - Assertions.assertTrue(foundTags.contains(testTag2), "Failed to create the tags testTag2 "); - // Check for creation of tags with channels - testTags.stream().filter(tag -> tag.getName().endsWith("WithChannels")).forEach( - (t) -> { - Optional testTagWithchannels = tagRepository.findById(t.getName(), true); - Assertions.assertTrue(testTagWithchannels.isPresent(), "failed to create test tag : " + t.getName()); - Assertions.assertSame(2, t.getChannels().size(), "failed to create tag with channels : " + t.getName()); - } - ); + // verify the tags were listed as expected + Assertions.assertEquals(createdTags, tagList, "Failed to list all tags"); + } + + /** read a single tag test the "withChannels" flag */ + @Test + void readXmlTag() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(testChannels()); + + Tag createdTag0 = tagManager.create(testTag0.getName(), testTag0); + Tag createdTag1 = tagManager.create(testTag1.getName(), testTag1); + + // verify the created tags are read as expected + // Retrieve the testTag0 without channels + Tag retrievedTag = tagManager.read(createdTag0.getName(), false); + Assertions.assertEquals(createdTag0, retrievedTag, "Failed to read the tag"); + // Retrieve the testTag0 with channels + retrievedTag = tagManager.read(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); + testTag1.setChannels(new ArrayList<>()); + Assertions.assertEquals(testTag1, retrievedTag, "Failed to read the tag"); + // Retrieve the testTag1 with channels + retrievedTag = tagManager.read(createdTag1.getName(), true); + Assertions.assertEquals(createdTag1, retrievedTag, "Failed to read the tag w/ channels"); + } + + /** attempt to read a single non existent tag */ + @Test + void readNonExistingXmlTag() { + // verify the tag failed to be read, as expected + Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.read("fakeTag", false)); + } + + /** attempt to read a single non existent tag with channels */ + @Test + void readNonExistingXmlTag2() { + // verify the tag failed to be read, as expected + Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.read("fakeTag", true)); + } + + /** create a simple tag */ + @Test + void createXmlTag() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + + // Create a simple tag + Tag createdTag = tagManager.create(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)); + Assertions.assertEquals(updatedTestTag0, createdTag, "Failed to create the tag"); + } + + /** Rename a simple tag using create */ + @Test + 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); + // 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 + Assertions.assertFalse( + tagRepository.existsById(testTag0.getName()), "Failed to replace the old tag"); + } + + /** Create a single tag with channels */ + @Test + void createXmlTag2() { + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(testChannels()); + + tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); + try { + Tag foundTag = tagRepository.findById(testTag0WithChannels.getName(), true).get(); + Tag expectedTag = new Tag("testTag0WithChannels", "testOwner"); + expectedTag.setChannels( + Arrays.asList( + new Channel( + "testChannel0", + "testOwner", + EMPTY_LIST, + List.of(new Tag("testTag0WithChannels", "testOwner"))), + new Channel( + "testChannel1", + "testOwner", + EMPTY_LIST, + List.of(new Tag("testTag0WithChannels", "testOwner"))))); + Assertions.assertEquals( + expectedTag, + foundTag, + "Failed to create the tag w/ channels. Expected " + + expectedTag.toLog() + + " found " + + foundTag.toLog()); + + } catch (Exception e) { + fail("Failed to create/find the tag w/ channels due to exception " + e.getMessage()); } - /** - * create by overriding multiple tags - *

- * attempting to change owners will have no effect - * changing channels will have an effect - */ - @Test - void createXmlTagsWithOverride() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - - Channel testChannel1 = testChannels().get(1); - - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(Arrays.asList(testChannel1)); - - 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)); - // 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)); - - // set owner back to original since it shouldn't change - testTag0.setOwner("testOwner"); - testTag0WithChannels.setOwner("testOwner"); - // verify the tags were updated as expected - Optional foundTag = tagRepository.findById(testTag0.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && foundTag.get().equals(testTag0), "Failed to update tag " + testTag0); - foundTag = tagRepository.findById(testTag0WithChannels.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && - foundTag.get().getChannels().size() == 1, "Failed to update tag " + testTag0WithChannels); - - testTag0WithChannels.setChannels(new ArrayList()); - testChannel1.setTags(Arrays.asList(testTag0WithChannels)); - MultiValueMap params = new LinkedMultiValueMap(); - params.add("~tag", testTag0WithChannels.getName()); - // verify the tag was removed from the old channels - Assertions.assertEquals(Arrays.asList(testChannel1), channelRepository.search(params).channels(), "Failed to change the channels the tag is attached to correctly"); - } - - /** - * add a single tag to a single channel - */ - @Test - void addSingleXmlTag() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - tagRepository.index(testTag0); - - tagManager.addSingle(testTag0.getName(), "testChannel0"); - Assertions.assertTrue(channelRepository.findById("testChannel0").get().getTags().stream().anyMatch(t -> t.getName().equals(testTag0.getName())), "Failed to add tag"); + Tag updatedTestTag0WithChannels = new Tag("testTag0WithChannels", "updateTestOwner"); + + tagManager.create(testTag0WithChannels.getName(), copy(updatedTestTag0WithChannels)); + try { + Tag foundTag = tagRepository.findById(updatedTestTag0WithChannels.getName(), true).get(); + // verify the tag was created as expected + Assertions.assertTrue( + tagCompare(updatedTestTag0WithChannels, foundTag), + "Failed to create the tag w/ channels"); + } catch (Exception e) { + fail("Failed to create/find the tag w/ channels"); } - - /** - * update a tag - */ - @Test - void updateXmlTag() { - // A test tag with only name and owner - Tag testTag0 = new Tag("testTag0", "testOwner"); - // A test tag with name, owner, and a single test channel - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0))); - - // 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)); - 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)); - Assertions.assertTrue(returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) && returnedTag.getChannels().size() == 1, "Failed to update tag " + testTag0WithChannels); - Assertions.assertSame(1, tagRepository.findById(testTag0WithChannels.getName(), true).get().getChannels().size(), "Failed to update tag " + testTag0WithChannels); - - // Update the tag owner - testTag0.setOwner("newTestOwner"); - returnedTag = tagManager.update(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)); - Assertions.assertTrue(returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) && - returnedTag.getChannels().size() == 1, "Failed to update tag " + testTag0WithChannels); - Optional queriedTag = tagRepository.findById(testTag0WithChannels.getName(), true); - Assertions.assertTrue(queriedTag.isPresent() && - queriedTag.get().getName().equalsIgnoreCase(testTag0WithChannels.getName()) && - queriedTag.get().getChannels().size() == 1, "Failed to update tag " + testTag0WithChannels); + } + + /** Rename a single tag with channels using create */ + @Test + void renameByCreateXmlTag2() { + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(testChannels()); + Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); + testTag1WithChannels.setChannels(testChannels()); + + // Create the testTag0WithChannels + tagManager.create(testTag0WithChannels.getName(), copy(testTag0WithChannels)); + // update the testTag0WithChannels with testTag1WithChannels + tagManager.create(testTag0WithChannels.getName(), copy(testTag1WithChannels)); + try { + Tag foundTag = tagRepository.findById(testTag1WithChannels.getName(), true).get(); + Assertions.assertFalse( + tagRepository.existsById("testTag0WithChannels"), + "Failed to rename the Tag - the old tag still exists"); + Assertions.assertTrue( + tagRepository.existsById("testTag1WithChannels"), + "Failed to rename the Tag - the new tag does not exists"); + Assertions.assertSame( + 2, + tagRepository.findById("testTag1WithChannels", true).get().getChannels().size(), + "Failed to rename the Tag - the new tag does have the channels"); + } catch (Exception e) { + fail("Failed to create/find the tag w/ channels"); } - - /** - * update a tag's name and owner on its channels - */ - @Test - void updateXmlTagOnChan() { - // extra channel for this test - Channel testChannelX = new Channel("testChannelX","testOwner"); - channelRepository.index(testChannelX); - // A test tag with name, owner, and 2 test channels - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0),testChannelX)); - // test tag with different name, owner, and 1 different channel & 1 existing channel - Tag testTag1WithChannels = new Tag("testTag1WithChannels", "updateTestOwner"); - testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(1),new Channel("testChannelX","testOwner"))); - + Assertions.assertFalse( + tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); + } + + /** create multiple tags */ + @Test + void createXmlTags() { + + Tag testTag0 = new Tag("testTag0", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner"); + Tag testTag2 = new Tag("testTag2", "testOwner"); + + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(testChannels()); + Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); + testTag1WithChannels.setChannels(testChannels()); + Tag testTag2WithChannels = new Tag("testTag2WithChannels", "testOwner"); + testTag2WithChannels.setChannels(testChannels()); + + List testTags = + Arrays.asList( + testTag0, + testTag1, + testTag2, + testTag0WithChannels, + testTag1WithChannels, + testTag2WithChannels); + + tagManager.create(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 "); + Assertions.assertTrue(foundTags.contains(testTag1), "Failed to create the tags testTag1 "); + Assertions.assertTrue(foundTags.contains(testTag2), "Failed to create the tags testTag2 "); + // Check for creation of tags with channels + testTags.stream() + .filter(tag -> tag.getName().endsWith("WithChannels")) + .forEach( + (t) -> { + Optional testTagWithchannels = tagRepository.findById(t.getName(), true); + Assertions.assertTrue( + testTagWithchannels.isPresent(), "failed to create test tag : " + t.getName()); + Assertions.assertSame( + 2, t.getChannels().size(), "failed to create tag with channels : " + t.getName()); + }); + } + + /** + * create by overriding multiple tags + * + *

attempting to change owners will have no effect changing channels will have an effect + */ + @Test + void createXmlTagsWithOverride() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + + Channel testChannel1 = testChannels().get(1); + + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(Arrays.asList(testChannel1)); + + 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)); + // 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)); + + // set owner back to original since it shouldn't change + testTag0.setOwner("testOwner"); + testTag0WithChannels.setOwner("testOwner"); + // verify the tags were updated as expected + Optional foundTag = tagRepository.findById(testTag0.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() && foundTag.get().equals(testTag0), + "Failed to update tag " + testTag0); + foundTag = tagRepository.findById(testTag0WithChannels.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() && foundTag.get().getChannels().size() == 1, + "Failed to update tag " + testTag0WithChannels); + + testTag0WithChannels.setChannels(new ArrayList()); + testChannel1.setTags(Arrays.asList(testTag0WithChannels)); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("~tag", testTag0WithChannels.getName()); + // verify the tag was removed from the old channels + Assertions.assertEquals( + Arrays.asList(testChannel1), + channelRepository.search(params).channels(), + "Failed to change the channels the tag is attached to correctly"); + } + + /** add a single tag to a single channel */ + @Test + void addSingleXmlTag() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + tagRepository.index(testTag0); + + tagManager.addSingle(testTag0.getName(), "testChannel0"); + Assertions.assertTrue( + channelRepository.findById("testChannel0").get().getTags().stream() + .anyMatch(t -> t.getName().equals(testTag0.getName())), + "Failed to add tag"); + } + + /** update a tag */ + @Test + void updateXmlTag() { + // A test tag with only name and owner + Tag testTag0 = new Tag("testTag0", "testOwner"); + // A test tag with name, owner, and a single test channel + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0))); + + // 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)); + 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)); + Assertions.assertTrue( + returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) + && returnedTag.getChannels().size() == 1, + "Failed to update tag " + testTag0WithChannels); + Assertions.assertSame( + 1, + tagRepository.findById(testTag0WithChannels.getName(), true).get().getChannels().size(), + "Failed to update tag " + testTag0WithChannels); + + // Update the tag owner + testTag0.setOwner("newTestOwner"); + returnedTag = tagManager.update(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)); + Assertions.assertTrue( + returnedTag.getName().equalsIgnoreCase(testTag0WithChannels.getName()) + && returnedTag.getChannels().size() == 1, + "Failed to update tag " + testTag0WithChannels); + Optional queriedTag = tagRepository.findById(testTag0WithChannels.getName(), true); + Assertions.assertTrue( + queriedTag.isPresent() + && queriedTag.get().getName().equalsIgnoreCase(testTag0WithChannels.getName()) + && queriedTag.get().getChannels().size() == 1, + "Failed to update tag " + testTag0WithChannels); + } + + /** update a tag's name and owner on its channels */ + @Test + void updateXmlTagOnChan() { + // extra channel for this test + Channel testChannelX = new Channel("testChannelX", "testOwner"); + channelRepository.index(testChannelX); + // A test tag with name, owner, and 2 test channels + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0), testChannelX)); + // test tag with different name, owner, and 1 different channel & 1 existing channel + Tag testTag1WithChannels = new Tag("testTag1WithChannels", "updateTestOwner"); + testTag1WithChannels.setChannels( + Arrays.asList(testChannels().get(1), new Channel("testChannelX", "testOwner"))); + + tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); + // change name and owner on existing channel, add to new channel + tagManager.update(testTag0WithChannels.getName(), testTag1WithChannels); + + Tag expectedTag = new Tag("testTag1WithChannels", "updateTestOwner"); + expectedTag.setChannels( + Arrays.asList( + new Channel("testChannel0", "testOwner"), + new Channel("testChannel1", "testOwner"), + new Channel("testChannelX", "testOwner"))); + // verify that the old tag "testTag0WithChannels" was replaced with the new + // "testTag1WithChannels" and lists of channels were combined + + Optional foundTag = tagRepository.findById(testTag1WithChannels.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() + && foundTag.get().getName().equalsIgnoreCase("testTag1WithChannels") + && foundTag.get().getChannels().size() == 3, + "Failed to update the tag"); + + // verify that the old tag is no longer present + Assertions.assertFalse( + tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); + + expectedTag = new Tag("testTag1WithChannels", "updateTestOwner"); + // test tag of old channel not in update + Assertions.assertTrue( + channelRepository + .findById(testChannels().get(0).getName()) + .get() + .getTags() + .contains(expectedTag), + "The tag attached to the channel " + + testChannels().get(0).toString() + + " doesn't match the new tag"); + // test tag of old channel and in update + Assertions.assertTrue( + channelRepository + .findById(testChannels().get(1).getName()) + .get() + .getTags() + .contains(expectedTag), + "The tag attached to the channel " + + testChannels().get(1).toString() + + " doesn't match the new tag"); + // test tag of new channel + Assertions.assertTrue( + channelRepository.findById(testChannelX.getName()).get().getTags().contains(expectedTag), + "The tag attached to the channel " + testChannelX + " doesn't match the new tag"); + + // clean extra channel + channelRepository.deleteById(testChannelX.getName()); + } + + /** Rename a tag using update */ + @Test + void renameByUpdateXmlTag() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner"); + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(testChannels()); + Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); + testTag1WithChannels.setChannels(testChannels()); + + // Create the original tags + Tag createdTag = tagManager.create(testTag0.getName(), testTag0); + Tag createdTagWithChannels = tagManager.create(testTag0WithChannels.getName(), testTag0WithChannels); - // change name and owner on existing channel, add to new channel + // update the tags with new names, 0 -> 1 + Tag updatedTag = tagManager.update(testTag0.getName(), testTag1); + Tag updatedTagWithChannels = tagManager.update(testTag0WithChannels.getName(), testTag1WithChannels); - - Tag expectedTag = new Tag("testTag1WithChannels", "updateTestOwner"); - expectedTag.setChannels(Arrays.asList( - new Channel("testChannel0", "testOwner"), - new Channel("testChannel1", "testOwner"), - new Channel("testChannelX","testOwner"))); - // verify that the old tag "testTag0WithChannels" was replaced with the new "testTag1WithChannels" and lists of channels were combined - - Optional foundTag = tagRepository.findById(testTag1WithChannels.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && - foundTag.get().getName().equalsIgnoreCase("testTag1WithChannels") && - foundTag.get().getChannels().size() == 3, "Failed to update the tag"); - - // verify that the old tag is no longer present - Assertions.assertFalse(tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); - - expectedTag = new Tag("testTag1WithChannels", "updateTestOwner"); - // test tag of old channel not in update - Assertions.assertTrue(channelRepository.findById(testChannels().get(0).getName()).get().getTags().contains(expectedTag), "The tag attached to the channel " + testChannels().get(0).toString() + " doesn't match the new tag"); - // test tag of old channel and in update - Assertions.assertTrue(channelRepository.findById(testChannels().get(1).getName()).get().getTags().contains(expectedTag), "The tag attached to the channel " + testChannels().get(1).toString() + " doesn't match the new tag"); - // test tag of new channel - Assertions.assertTrue(channelRepository.findById(testChannelX.getName()).get().getTags().contains(expectedTag), "The tag attached to the channel " + testChannelX + " doesn't match the new tag"); - - // clean extra channel - channelRepository.deleteById(testChannelX.getName()); - } - - /** - * Rename a tag using update - */ - @Test - void renameByUpdateXmlTag() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - Tag testTag1 = new Tag("testTag1", "testOwner"); - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(testChannels()); - Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); - testTag1WithChannels.setChannels(testChannels()); - - // Create the original tags - Tag createdTag = tagManager.create(testTag0.getName(), testTag0); - Tag createdTagWithChannels = tagManager.create(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); - - // verify that the old tag "testTag0" was replaced with the new "testTag1" - Optional foundTag = tagRepository.findById(testTag1.getName()); - Assertions.assertTrue(foundTag.isPresent(), "Failed to update the tag"); - // verify that the old tag is no longer present - Assertions.assertFalse(tagRepository.existsById(testTag0.getName()), "Failed to replace the old tag"); - - // verify that the old tag "testTag0WithChannels" was replaced with the new "testTag1WithChannels" - foundTag = tagRepository.findById(testTag1WithChannels.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && foundTag.get().getChannels().size() == 2, "Failed to update the tag w/ channels"); - // verify that the old tag is no longer present - Assertions.assertFalse(tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); - - // TODO add test for failure case - } - - /** - * Update the channels associated with a tag - * Existing tag channels: none | update tag channels: testChannel0 - * Resultant tag channels: testChannel0 - */ - @Test - void updateTagTest1() { - // A test tag with only name and owner - Tag testTag0 = new Tag("testTag0", "testOwner"); - tagManager.create(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)); - Assertions.assertEquals(returnedTag, tagRepository.findById(testTag0.getName(), true).get(), "Failed to update tag " + returnedTag); - } - - /** - * Update the channels associated with a tag - * Existing tag channels: testChannel0 | update tag channels: testChannel1 - * Resultant tag channels: testChannel0,testChannel1 - */ - @Test - 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); - 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)); - - // Query ChannelFinder and verify updated channels and tags - Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); - Assertions.assertSame(2, foundTag.getChannels().size(), "Failed to update tag " + testTag0); - } - - /** - * Update the channels associated with a tag. - * Existing tag channels: testChannel0 | update tag channels: testChannel0,testChannel1 - * Resultant tag channels: testChannel0,testChannel1 - */ - @Test - void updateTagTest3() { - // A test tag with testChannel0 - Tag testTag0 = new Tag("testTag0", "testOwner"); - testTag0.setChannels(Arrays.asList(testChannels().get(0))); - - tagManager.create(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)); - - // Query ChannelFinder and verify updated channels and tags - Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); - - Tag expectedChannelTag = new Tag("testTag0", "testOwner"); - Assertions.assertTrue(foundTag.getChannels().containsAll(Arrays.asList( - new Channel("testChannel0", "testOwner", EMPTY_LIST, Arrays.asList(expectedChannelTag)), - new Channel("testChannel1", "testOwner", EMPTY_LIST, Arrays.asList(expectedChannelTag)))), "Failed to update tag " + testTag0.toLog()); - } - - /** - * Update the channels associated with a tag - * Existing tag channels: testChannel0,testChannel1 | update tag channels: testChannel0,testChannel1 - * Resultant tag channels: testChannel0,testChannel1 - */ - @Test - void updateTagTest4() { - // A test tag with testChannel0,testChannel1 - Tag testTag0 = new Tag("testTag0", "testOwner"); - testTag0.setChannels(testChannels()); - - // Updating a tag with existing channels, the new channels should be added without affecting 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)); - 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); - expectedTag.setChannels(Arrays.asList( - new Channel("testChannel0", "testOwner", EMPTY_LIST, Arrays.asList(new Tag("testTag0", "testOwner"))), - new Channel("testChannel1", "testOwner", EMPTY_LIST, Arrays.asList(new Tag("testTag0", "testOwner"))))); - Assertions.assertEquals(expectedTag, foundTag, "Failed to update tag " + testTag0); - } - /** - * Update the channels associated with a tag - * Existing tag channels: testChannel0,testChannel1 | update tag channels: testChannel0 - * Resultant tag channels: testChannel0,testChannel1 - */ - @Test - void updateTagTest5() { - // A test tag with testChannel0,testChannel1 - Tag testTag0 = new Tag("testTag0", "testOwner"); - testTag0.setChannels(testChannels()); - Tag expectedTag = tagManager.create(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)); - 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(); - - expectedTag.setChannels(Arrays.asList(new Channel("testChannel0", "testOwner"))); - expectedTag.setChannels(Arrays.asList( - new Channel("testChannel0", "testOwner", EMPTY_LIST, Arrays.asList(new Tag("testTag0", "testOwner"))), - new Channel("testChannel1", "testOwner", EMPTY_LIST, Arrays.asList(new Tag("testTag0", "testOwner"))))); - Assertions.assertEquals(expectedTag, foundTag, "Failed to update tag " + testTag0); - } - - /** - * Update multiple tags - * Update on non-existing tags should result in the creation of the tags - */ - @Test - void updateMultipleTags() { - // A test tag with only name and owner - Tag testTag0 = new Tag("testTag0", "testOwner"); - // A test tag with name, owner, and test channels - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(testChannels()); - - Iterable returnedTag = tagManager.update(Arrays.asList(copy(testTag0), copy(testTag0WithChannels))); - // Query ChannelFinder and verify updated channels and tags - Optional foundTag = tagRepository.findById(testTag0.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && foundTag.get().equals(testTag0), "Failed to update tag " + testTag0.toLog()); - foundTag = tagRepository.findById(testTag0WithChannels.getName(), true); - Assertions.assertTrue(foundTag.isPresent() && foundTag.get().getChannels().size() == 2, "Failed to update tag with channels " + testTag0WithChannels.toLog()); - } - - /** - * update tags' names and attempt to change owners on their channels - */ - @Test - void updateMultipleXmlTagsOnChan() { - // extra channel for this test - Channel testChannelX = new Channel("testChannelX","testOwner"); - channelRepository.index(testChannelX); - - // 2 test tags with name, owner, and channels - Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); - testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0),testChannelX)); - Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); - testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(1),testChannelX)); - - tagManager.create(Arrays.asList(testTag0WithChannels,testTag1WithChannels)); - // change owners and add channels - testTag0WithChannels.setOwner("updateTestOwner"); - testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(1),testChannelX)); - testTag1WithChannels.setOwner("updateTestOwner"); - testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(0),testChannelX)); - - // update both tags - tagManager.update(Arrays.asList(testTag0WithChannels,testTag1WithChannels)); - - // verify that the tags were updated - Tag foundTag0 = tagRepository.findById(testTag0WithChannels.getName(), true).get(); - Assertions.assertSame(3, foundTag0.getChannels().size(), "Failed to update the tag " + testTag0WithChannels.getName()); - Tag foundTag1 = tagRepository.findById(testTag1WithChannels.getName(), true).get(); - Assertions.assertSame(3, foundTag0.getChannels().size(), "Failed to update the tag " + testTag0WithChannels.getName()); - - Tag expectedTag0 = new Tag("testTag0WithChannels", "testOwner"); - Tag expectedTag1 = new Tag("testTag1WithChannels", "testOwner"); - List expectedTags = Arrays.asList(expectedTag0,expectedTag1); - // check if tags attached to channels are correct - // test tag of channel0 - Assertions.assertEquals(expectedTags, channelRepository.findById(testChannels().get(0).getName()).get().getTags(), "The tags attached to the channel " + testChannels().get(0).toString() + " doesn't match the expected tags"); - // test tag of channel1 (tags need to be sorted because they are not sorted when gotten from channel) - List sortedTags = channelRepository.findById(testChannels().get(1).getName()).get().getTags(); - sortedTags.sort(Comparator.comparing(Tag::getName)); - Assertions.assertEquals(expectedTags, sortedTags, "The tags attached to the channel " + testChannels().get(1).toString() + " doesn't match the expected tags"); - // test tag of channelX - Assertions.assertEquals(expectedTags, channelRepository.findById(testChannelX.getName()).get().getTags(), "The tags attached to the channel " + testChannelX + " doesn't match the expected tags"); - - } - - /** - * delete a single tag - */ - @Test - void deleteXmlTag() { - Tag testTag0 = new Tag("testTag0", "testOwner"); - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(testChannels()); - List testTags = Arrays.asList(testTag0,testTag1); - - Iterable createdTags = tagManager.create(testTags); - - tagManager.remove(testTag0.getName()); - // verify the tag was deleted as expected - Assertions.assertFalse(tagRepository.existsById(testTag0.getName()), "Failed to delete the tag"); - - tagManager.remove(testTag1.getName()); - MultiValueMap params = new LinkedMultiValueMap(); - params.add("~tag", testTag1.getName()); - // verify the tag was deleted and removed from all associated channels - Assertions.assertFalse(tagRepository.existsById(testTag1.getName()), "Failed to delete the tag"); - Assertions.assertEquals(new ArrayList(), channelRepository.search(params).channels(), "Failed to delete the tag from channels"); - } - - /** - * delete a single tag from a single channel - */ - @Test - void deleteXmlTagFromChannel() { - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(testChannels()); - - Tag createdTag = tagManager.create(testTag1.getName(),testTag1); - - tagManager.removeSingle(testTag1.getName(),testChannels().get(0).getName()); - // verify the tag was only removed from the single test channel - Assertions.assertTrue(tagRepository.existsById(testTag1.getName()), "Failed to not delete the tag"); - - // Verify the tag is removed from the testChannel0 - MultiValueMap searchParameters = new LinkedMultiValueMap(); - searchParameters.add("~tag", testTag1.getName()); - Assertions.assertFalse(channelRepository.search(searchParameters).channels().stream().anyMatch(ch -> { - return ch.getName().equals(testChannels().get(0).getName()); - }), "Failed to delete the tag from channel"); - } - - // A set of test channels populated into channelfinder for test purposes. These - // channels are added and removed before each test - - private static List testChannels() {return Arrays.asList( - new Channel("testChannel0", "testOwner"), - new Channel("testChannel1", "testOwner")); - } - - @BeforeEach - public void setup() { - channelRepository.indexAll(testChannels()); - - } - - @AfterEach - public void cleanup() { - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); - } - - /** - * Compare the two tags ignoring the order of the associated channels - * @param tag1 - * @param tag2 - * @return true is the tags match - */ - private static boolean tagCompare(Tag tag1, Tag tag2) { - if(!(tag1.getName().equals(tag2.getName())) || !(tag1.getOwner().equals(tag2.getOwner()))) - return false; - return tag1.getChannels().containsAll(tag2.getChannels()) && tag2.getChannels().containsAll(tag1.getChannels()); - } - - private static Tag copy(Tag tag) { - Tag copy = new Tag(tag.getName(),tag.getOwner()); - List channels = new ArrayList(); - tag.getChannels().forEach(chan -> channels.add(new Channel(chan.getName(),chan.getOwner()))); - copy.setChannels(channels); - return copy; - } - - private static List copy(List tags) { - List copy = new ArrayList(); - tags.forEach(tag -> copy.add(copy(tag))); - return copy; - } -} \ No newline at end of file + // verify that the old tag "testTag0" was replaced with the new "testTag1" + Optional foundTag = tagRepository.findById(testTag1.getName()); + Assertions.assertTrue(foundTag.isPresent(), "Failed to update the tag"); + // verify that the old tag is no longer present + Assertions.assertFalse( + tagRepository.existsById(testTag0.getName()), "Failed to replace the old tag"); + + // verify that the old tag "testTag0WithChannels" was replaced with the new + // "testTag1WithChannels" + foundTag = tagRepository.findById(testTag1WithChannels.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() && foundTag.get().getChannels().size() == 2, + "Failed to update the tag w/ channels"); + // verify that the old tag is no longer present + Assertions.assertFalse( + tagRepository.existsById(testTag0WithChannels.getName()), "Failed to replace the old tag"); + + // TODO add test for failure case + } + + /** + * Update the channels associated with a tag Existing tag channels: none | update tag channels: + * testChannel0 Resultant tag channels: testChannel0 + */ + @Test + void updateTagTest1() { + // A test tag with only name and owner + Tag testTag0 = new Tag("testTag0", "testOwner"); + tagManager.create(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)); + Assertions.assertEquals( + returnedTag, + tagRepository.findById(testTag0.getName(), true).get(), + "Failed to update tag " + returnedTag); + } + + /** + * Update the channels associated with a tag Existing tag channels: testChannel0 | update tag + * channels: testChannel1 Resultant tag channels: testChannel0,testChannel1 + */ + @Test + 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); + 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)); + + // Query ChannelFinder and verify updated channels and tags + Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); + Assertions.assertSame(2, foundTag.getChannels().size(), "Failed to update tag " + testTag0); + } + + /** + * Update the channels associated with a tag. Existing tag channels: testChannel0 | update tag + * channels: testChannel0,testChannel1 Resultant tag channels: testChannel0,testChannel1 + */ + @Test + void updateTagTest3() { + // A test tag with testChannel0 + Tag testTag0 = new Tag("testTag0", "testOwner"); + testTag0.setChannels(Arrays.asList(testChannels().get(0))); + + tagManager.create(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)); + + // Query ChannelFinder and verify updated channels and tags + Tag foundTag = tagRepository.findById(testTag0.getName(), true).get(); + + Tag expectedChannelTag = new Tag("testTag0", "testOwner"); + Assertions.assertTrue( + foundTag + .getChannels() + .containsAll( + Arrays.asList( + new Channel( + "testChannel0", "testOwner", EMPTY_LIST, Arrays.asList(expectedChannelTag)), + new Channel( + "testChannel1", + "testOwner", + EMPTY_LIST, + Arrays.asList(expectedChannelTag)))), + "Failed to update tag " + testTag0.toLog()); + } + + /** + * Update the channels associated with a tag Existing tag channels: testChannel0,testChannel1 | + * update tag channels: testChannel0,testChannel1 Resultant tag channels: + * testChannel0,testChannel1 + */ + @Test + void updateTagTest4() { + // A test tag with testChannel0,testChannel1 + Tag testTag0 = new Tag("testTag0", "testOwner"); + testTag0.setChannels(testChannels()); + + // Updating a tag with existing channels, the new channels should be added without affecting + // 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)); + 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); + expectedTag.setChannels( + Arrays.asList( + new Channel( + "testChannel0", + "testOwner", + EMPTY_LIST, + Arrays.asList(new Tag("testTag0", "testOwner"))), + new Channel( + "testChannel1", + "testOwner", + EMPTY_LIST, + Arrays.asList(new Tag("testTag0", "testOwner"))))); + Assertions.assertEquals(expectedTag, foundTag, "Failed to update tag " + testTag0); + } + + /** + * Update the channels associated with a tag Existing tag channels: testChannel0,testChannel1 | + * update tag channels: testChannel0 Resultant tag channels: testChannel0,testChannel1 + */ + @Test + void updateTagTest5() { + // A test tag with testChannel0,testChannel1 + Tag testTag0 = new Tag("testTag0", "testOwner"); + testTag0.setChannels(testChannels()); + Tag expectedTag = tagManager.create(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)); + 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(); + + expectedTag.setChannels(Arrays.asList(new Channel("testChannel0", "testOwner"))); + expectedTag.setChannels( + Arrays.asList( + new Channel( + "testChannel0", + "testOwner", + EMPTY_LIST, + Arrays.asList(new Tag("testTag0", "testOwner"))), + new Channel( + "testChannel1", + "testOwner", + EMPTY_LIST, + Arrays.asList(new Tag("testTag0", "testOwner"))))); + Assertions.assertEquals(expectedTag, foundTag, "Failed to update tag " + testTag0); + } + + /** Update multiple tags Update on non-existing tags should result in the creation of the tags */ + @Test + void updateMultipleTags() { + // A test tag with only name and owner + Tag testTag0 = new Tag("testTag0", "testOwner"); + // A test tag with name, owner, and test channels + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(testChannels()); + + Iterable returnedTag = + tagManager.update(Arrays.asList(copy(testTag0), copy(testTag0WithChannels))); + // Query ChannelFinder and verify updated channels and tags + Optional foundTag = tagRepository.findById(testTag0.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() && foundTag.get().equals(testTag0), + "Failed to update tag " + testTag0.toLog()); + foundTag = tagRepository.findById(testTag0WithChannels.getName(), true); + Assertions.assertTrue( + foundTag.isPresent() && foundTag.get().getChannels().size() == 2, + "Failed to update tag with channels " + testTag0WithChannels.toLog()); + } + + /** update tags' names and attempt to change owners on their channels */ + @Test + void updateMultipleXmlTagsOnChan() { + // extra channel for this test + Channel testChannelX = new Channel("testChannelX", "testOwner"); + channelRepository.index(testChannelX); + + // 2 test tags with name, owner, and channels + Tag testTag0WithChannels = new Tag("testTag0WithChannels", "testOwner"); + testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(0), testChannelX)); + Tag testTag1WithChannels = new Tag("testTag1WithChannels", "testOwner"); + testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(1), testChannelX)); + + tagManager.create(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); + // change owners and add channels + testTag0WithChannels.setOwner("updateTestOwner"); + testTag0WithChannels.setChannels(Arrays.asList(testChannels().get(1), testChannelX)); + testTag1WithChannels.setOwner("updateTestOwner"); + testTag1WithChannels.setChannels(Arrays.asList(testChannels().get(0), testChannelX)); + + // update both tags + tagManager.update(Arrays.asList(testTag0WithChannels, testTag1WithChannels)); + + // verify that the tags were updated + Tag foundTag0 = tagRepository.findById(testTag0WithChannels.getName(), true).get(); + Assertions.assertSame( + 3, + foundTag0.getChannels().size(), + "Failed to update the tag " + testTag0WithChannels.getName()); + Tag foundTag1 = tagRepository.findById(testTag1WithChannels.getName(), true).get(); + Assertions.assertSame( + 3, + foundTag0.getChannels().size(), + "Failed to update the tag " + testTag0WithChannels.getName()); + + Tag expectedTag0 = new Tag("testTag0WithChannels", "testOwner"); + Tag expectedTag1 = new Tag("testTag1WithChannels", "testOwner"); + List expectedTags = Arrays.asList(expectedTag0, expectedTag1); + // check if tags attached to channels are correct + // test tag of channel0 + Assertions.assertEquals( + expectedTags, + channelRepository.findById(testChannels().get(0).getName()).get().getTags(), + "The tags attached to the channel " + + testChannels().get(0).toString() + + " doesn't match the expected tags"); + // test tag of channel1 (tags need to be sorted because they are not sorted when gotten from + // channel) + List sortedTags = + channelRepository.findById(testChannels().get(1).getName()).get().getTags(); + sortedTags.sort(Comparator.comparing(Tag::getName)); + Assertions.assertEquals( + expectedTags, + sortedTags, + "The tags attached to the channel " + + testChannels().get(1).toString() + + " doesn't match the expected tags"); + // test tag of channelX + Assertions.assertEquals( + expectedTags, + channelRepository.findById(testChannelX.getName()).get().getTags(), + "The tags attached to the channel " + testChannelX + " doesn't match the expected tags"); + } + + /** delete a single tag */ + @Test + void deleteXmlTag() { + Tag testTag0 = new Tag("testTag0", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(testChannels()); + List testTags = Arrays.asList(testTag0, testTag1); + + Iterable createdTags = tagManager.create(testTags); + + tagManager.remove(testTag0.getName()); + // verify the tag was deleted as expected + Assertions.assertFalse( + tagRepository.existsById(testTag0.getName()), "Failed to delete the tag"); + + tagManager.remove(testTag1.getName()); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("~tag", testTag1.getName()); + // verify the tag was deleted and removed from all associated channels + Assertions.assertFalse( + tagRepository.existsById(testTag1.getName()), "Failed to delete the tag"); + Assertions.assertEquals( + new ArrayList(), + channelRepository.search(params).channels(), + "Failed to delete the tag from channels"); + } + + /** delete a single tag from a single channel */ + @Test + void deleteXmlTagFromChannel() { + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(testChannels()); + + Tag createdTag = tagManager.create(testTag1.getName(), testTag1); + + tagManager.removeSingle(testTag1.getName(), testChannels().get(0).getName()); + // verify the tag was only removed from the single test channel + Assertions.assertTrue( + tagRepository.existsById(testTag1.getName()), "Failed to not delete the tag"); + + // Verify the tag is removed from the testChannel0 + MultiValueMap searchParameters = new LinkedMultiValueMap(); + searchParameters.add("~tag", testTag1.getName()); + Assertions.assertFalse( + channelRepository.search(searchParameters).channels().stream() + .anyMatch( + ch -> { + return ch.getName().equals(testChannels().get(0).getName()); + }), + "Failed to delete the tag from channel"); + } + + // A set of test channels populated into channelfinder for test purposes. These + // channels are added and removed before each test + + private static List testChannels() { + return Arrays.asList( + new Channel("testChannel0", "testOwner"), new Channel("testChannel1", "testOwner")); + } + + @BeforeEach + public void setup() { + channelRepository.indexAll(testChannels()); + } + + @AfterEach + public void cleanup() { + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); + } + + /** + * Compare the two tags ignoring the order of the associated channels + * + * @param tag1 + * @param tag2 + * @return true is the tags match + */ + private static boolean tagCompare(Tag tag1, Tag tag2) { + if (!(tag1.getName().equals(tag2.getName())) || !(tag1.getOwner().equals(tag2.getOwner()))) + return false; + return tag1.getChannels().containsAll(tag2.getChannels()) + && tag2.getChannels().containsAll(tag1.getChannels()); + } + + private static Tag copy(Tag tag) { + Tag copy = new Tag(tag.getName(), tag.getOwner()); + List channels = new ArrayList(); + tag.getChannels().forEach(chan -> channels.add(new Channel(chan.getName(), chan.getOwner()))); + copy.setChannels(channels); + return copy; + } + + private static List copy(List tags) { + List copy = new ArrayList(); + tags.forEach(tag -> copy.add(copy(tag))); + return copy; + } +} diff --git a/src/test/java/org/phoebus/channelfinder/TagRepositoryIT.java b/src/test/java/org/phoebus/channelfinder/TagRepositoryIT.java index fa7dda17..10c37a01 100644 --- a/src/test/java/org/phoebus/channelfinder/TagRepositoryIT.java +++ b/src/test/java/org/phoebus/channelfinder/TagRepositoryIT.java @@ -1,6 +1,12 @@ package org.phoebus.channelfinder; import com.google.common.collect.Sets; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -15,236 +21,221 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(TagRepository.class) @TestPropertySource(value = "classpath:application_test.properties") class TagRepositoryIT { - @Autowired - ElasticConfig esService; - - @Autowired - TagRepository tagRepository; - - @Autowired - ChannelRepository channelRepository; - - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); + @Autowired ElasticConfig esService; + + @Autowired TagRepository tagRepository; + + @Autowired ChannelRepository channelRepository; + + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } + + /** index a single tag */ + @Test + void indexXmlTag() { + Tag testTag = new Tag("testTag", "testOwner"); + cleanupTestTags = List.of(testTag); + + Tag createdTag = tagRepository.index(testTag); + // verify the tag was created as expected + Assertions.assertEquals(testTag, createdTag, "Failed to create the tag"); + } + + /** index multiple tags */ + @Test + void indexXmlTags() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner1"); + List testTags = Arrays.asList(testTag, testTag1); + cleanupTestTags = testTags; + + Iterable createdTags = tagRepository.indexAll(testTags); + // verify the tags were created as expected + Assertions.assertEquals(testTags, createdTags, "Failed to create the list of tags"); + } + + /** save a single tag */ + @Test + void saveXmlTag() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag updateTestTag = new Tag("testTag", "updateTestOwner"); + Tag updateTestTag1 = new Tag("testTag1", "updateTestOwner1"); + cleanupTestTags = Arrays.asList(testTag, updateTestTag, updateTestTag1); + + Tag createdTag = tagRepository.index(testTag); + Tag updatedTestTag = tagRepository.save(updateTestTag); + // verify the tag was updated as expected + Assertions.assertEquals( + updateTestTag, updatedTestTag, "Failed to update the tag with the same name"); + + Tag updatedTestTag1 = tagRepository.save("testTag", updateTestTag1); + // verify the tag was updated as expected + Assertions.assertEquals( + updateTestTag1, updatedTestTag1, "Failed to update the tag with a different name"); + } + + /** save multiple tags */ + @Test + void saveXmlTags() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner1"); + Tag updateTestTag = new Tag("testTag", "updateTestOwner"); + Tag updateTestTag1 = new Tag("testTag1", "updateTestOwner1"); + List testTags = Arrays.asList(testTag, testTag1); + List updateTestTags = Arrays.asList(updateTestTag, updateTestTag1); + cleanupTestTags = updateTestTags; + + Iterable createdTags = tagRepository.indexAll(testTags); + Iterable updatedTestTags = tagRepository.saveAll(updateTestTags); + // verify the tags were updated as expected + Assertions.assertEquals(updateTestTags, updatedTestTags, "Failed to update the tags"); + } + + /** find a single tag */ + @Test + void findXmlTag() { + Tag testTag = new Tag("testTag", "testOwner"); + cleanupTestTags = Arrays.asList(testTag); + + Optional notFoundTag = tagRepository.findById(testTag.getName()); + // verify the tag was not found as expected + Assertions.assertTrue( + notFoundTag.isEmpty(), "Found the test tag which has not yet been created"); + + Tag createdTag = tagRepository.index(testTag); + Optional foundTag = tagRepository.findById(createdTag.getName()); + // verify the tag was found as expected + Assertions.assertEquals(createdTag, foundTag.get(), "Failed to create/find the test tag"); + + // Create a channel with the test tag and find a tag with its associated channels + Channel channel = new Channel("testChannel", "testOwner", null, Arrays.asList(createdTag)); + Channel createdChannel = channelRepository.index(channel); + + foundTag = tagRepository.findById(createdTag.getName(), true); + createdTag.setChannels(Arrays.asList(new Channel(channel.getName(), channel.getOwner()))); + // verify the tag was found as expected + + Tag expectedTag = new Tag(createdTag.getName(), createdTag.getOwner()); + expectedTag.setChannels(Arrays.asList(createdChannel)); + Assertions.assertEquals(expectedTag, foundTag.get(), "Failed to find the tag"); + + // channel clean up + channelRepository.deleteById(createdChannel.getName()); + } + + /** check if a tag exists */ + @Test + void testTagExists() { + Tag testTag = new Tag("testTag", "testOwner"); + cleanupTestTags = Arrays.asList(testTag); + + Tag createdTag = tagRepository.index(testTag); + // verify the tag exists as expected + Assertions.assertTrue( + tagRepository.existsById(testTag.getName()), + "Failed to check the existance of " + testTag.getName()); + // verify the tag does not exist, as expected + Assertions.assertFalse( + tagRepository.existsById("non-existant-tag"), + "Failed to check the non-existance of 'non-existant-tag'"); + } + + /** find all tags */ + @Test + void findAllXmlTags() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner1"); + List testTags = Arrays.asList(testTag, testTag1); + cleanupTestTags = testTags; + + try { + Set createdTags = Sets.newHashSet(tagRepository.indexAll(testTags)); + Set listedTags = Sets.newHashSet(tagRepository.findAll()); + // verify the tag was created as expected + Assertions.assertEquals(listedTags, createdTags, "Failed to list all created tags"); + } catch (Exception e) { + Assertions.fail(e); } - /** - * index a single tag - */ - @Test - void indexXmlTag() { - Tag testTag = new Tag("testTag","testOwner"); - cleanupTestTags = List.of(testTag); - - Tag createdTag = tagRepository.index(testTag); - // verify the tag was created as expected - Assertions.assertEquals(testTag, createdTag, "Failed to create the tag"); + } + + /** find multiple tags */ + @Test + void findXmlTags() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag testTag1 = new Tag("testTag1", "testOwner1"); + List testTags = Arrays.asList(testTag, testTag1); + List tagNames = Arrays.asList(testTag.getName(), testTag1.getName()); + Iterable notFoundTags = null; + Iterable foundTags = null; + cleanupTestTags = testTags; + + try { + notFoundTags = tagRepository.findAllById(tagNames); + } catch (ResponseStatusException e) { + } finally { + // verify the tags were not found as expected + Assertions.assertNotEquals(testTags, notFoundTags, "Found the tags"); } - /** - * index multiple tags - */ - @Test - void indexXmlTags() { - Tag testTag = new Tag("testTag","testOwner"); - Tag testTag1 = new Tag("testTag1","testOwner1"); - List testTags = Arrays.asList(testTag, testTag1); - cleanupTestTags = testTags; - - Iterable createdTags = tagRepository.indexAll(testTags); - // verify the tags were created as expected - Assertions.assertEquals(testTags, createdTags, "Failed to create the list of tags"); - } - - /** - * save a single tag - */ - @Test - void saveXmlTag() { - Tag testTag = new Tag("testTag","testOwner"); - Tag updateTestTag = new Tag("testTag","updateTestOwner"); - Tag updateTestTag1 = new Tag("testTag1","updateTestOwner1"); - cleanupTestTags = Arrays.asList(testTag,updateTestTag,updateTestTag1); - - Tag createdTag = tagRepository.index(testTag); - Tag updatedTestTag = tagRepository.save(updateTestTag); - // verify the tag was updated as expected - Assertions.assertEquals(updateTestTag, updatedTestTag, "Failed to update the tag with the same name"); - - Tag updatedTestTag1 = tagRepository.save("testTag",updateTestTag1); - // verify the tag was updated as expected - Assertions.assertEquals(updateTestTag1, updatedTestTag1, "Failed to update the tag with a different name"); - } - - /** - * save multiple tags - */ - @Test - void saveXmlTags() { - Tag testTag = new Tag("testTag","testOwner"); - Tag testTag1 = new Tag("testTag1","testOwner1"); - Tag updateTestTag = new Tag("testTag","updateTestOwner"); - Tag updateTestTag1 = new Tag("testTag1","updateTestOwner1"); - List testTags = Arrays.asList(testTag, testTag1); - List updateTestTags = Arrays.asList(updateTestTag, updateTestTag1); - cleanupTestTags = updateTestTags; - - Iterable createdTags = tagRepository.indexAll(testTags); - Iterable updatedTestTags = tagRepository.saveAll(updateTestTags); - // verify the tags were updated as expected - Assertions.assertEquals(updateTestTags, updatedTestTags, "Failed to update the tags"); - } - - /** - * find a single tag - */ - @Test - void findXmlTag() { - Tag testTag = new Tag("testTag","testOwner"); - cleanupTestTags = Arrays.asList(testTag); - - Optional notFoundTag = tagRepository.findById(testTag.getName()); - // verify the tag was not found as expected - Assertions.assertTrue(notFoundTag.isEmpty(), "Found the test tag which has not yet been created"); - - Tag createdTag = tagRepository.index(testTag); - Optional foundTag = tagRepository.findById(createdTag.getName()); - // verify the tag was found as expected - Assertions.assertEquals(createdTag, foundTag.get(), "Failed to create/find the test tag"); - - // Create a channel with the test tag and find a tag with its associated channels - Channel channel = new Channel("testChannel","testOwner",null,Arrays.asList(createdTag)); - Channel createdChannel = channelRepository.index(channel); - - foundTag = tagRepository.findById(createdTag.getName(),true); - createdTag.setChannels(Arrays.asList(new Channel(channel.getName(),channel.getOwner()))); - // verify the tag was found as expected - - Tag expectedTag = new Tag(createdTag.getName(), createdTag.getOwner()); - expectedTag.setChannels(Arrays.asList(createdChannel)); - Assertions.assertEquals(expectedTag, foundTag.get(), "Failed to find the tag"); - - // channel clean up - channelRepository.deleteById(createdChannel.getName()); - } - - /** - * check if a tag exists - */ - @Test - void testTagExists() { - Tag testTag = new Tag("testTag","testOwner"); - cleanupTestTags = Arrays.asList(testTag); - - Tag createdTag = tagRepository.index(testTag); - // verify the tag exists as expected - Assertions.assertTrue(tagRepository.existsById(testTag.getName()), "Failed to check the existance of " + testTag.getName()); - // verify the tag does not exist, as expected - Assertions.assertFalse(tagRepository.existsById("non-existant-tag"), "Failed to check the non-existance of 'non-existant-tag'"); - } - - /** - * find all tags - */ - @Test - void findAllXmlTags() { - Tag testTag = new Tag("testTag","testOwner"); - Tag testTag1 = new Tag("testTag1","testOwner1"); - List testTags = Arrays.asList(testTag, testTag1); - cleanupTestTags = testTags; - - try { - Set createdTags = Sets.newHashSet(tagRepository.indexAll(testTags)); - Set listedTags = Sets.newHashSet(tagRepository.findAll()); - // verify the tag was created as expected - Assertions.assertEquals(listedTags, createdTags, "Failed to list all created tags"); - } catch (Exception e) { - Assertions.fail(e); } - } - - /** - * find multiple tags - */ - @Test - void findXmlTags() { - Tag testTag = new Tag("testTag","testOwner"); - Tag testTag1 = new Tag("testTag1","testOwner1"); - List testTags = Arrays.asList(testTag,testTag1); - List tagNames = Arrays.asList(testTag.getName(),testTag1.getName()); - Iterable notFoundTags = null; - Iterable foundTags = null; - cleanupTestTags = testTags; - - try { - notFoundTags = tagRepository.findAllById(tagNames); - } catch (ResponseStatusException e) { - } finally { - // verify the tags were not found as expected - Assertions.assertNotEquals(testTags, notFoundTags, "Found the tags"); - } - - Iterable createdTags = tagRepository.indexAll(testTags); - - try { - foundTags = tagRepository.findAllById(tagNames); - } catch (ResponseStatusException e) { - } finally { - // verify the tags were found as expected - Assertions.assertEquals(createdTags, foundTags, "Failed to find the tags"); - } - } - - /** - * delete a single tag - */ - @Test - void deleteXmlTag() { - Tag testTag = new Tag("testTag","testOwner"); - Tag createdTag = tagRepository.index(testTag); - Channel channel = new Channel("testChannel","testOwner",null,Arrays.asList(createdTag)); - cleanupTestTags = Arrays.asList(testTag); - - Channel createdChannel = channelRepository.index(channel); - tagRepository.deleteById(createdTag.getName()); - // verify the tag was deleted as expected - Assertions.assertNotEquals(testTag, tagRepository.findById(testTag.getName()), "Failed to delete tag"); - - // verify the tag was deleted from channels as expected - Channel foundChannel = channelRepository.findById("testChannel").get(); - Assertions.assertTrue(foundChannel.getTags().isEmpty(), "Failed to remove tag from channel"); - - // verify the tag was deleted from all channels as expected - MultiValueMap params = new LinkedMultiValueMap(); - params.add("~tag","testChannel"); - List chans = channelRepository.search(params).channels(); - Assertions.assertTrue(chans.isEmpty(), "Failed to remove tag from channel"); - - // channel clean up - channelRepository.deleteById(createdChannel.getName()); - } + Iterable createdTags = tagRepository.indexAll(testTags); - // helper operations to clean up tagrepoIT - - private List cleanupTestTags = Collections.emptyList(); - - @AfterEach - public void cleanup() { - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.set("~name", "*"); - channelRepository.search(map).channels().forEach(c -> channelRepository.deleteById(c.getName())); - tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); + try { + foundTags = tagRepository.findAllById(tagNames); + } catch (ResponseStatusException e) { + } finally { + // verify the tags were found as expected + Assertions.assertEquals(createdTags, foundTags, "Failed to find the tags"); } -} \ No newline at end of file + } + + /** delete a single tag */ + @Test + void deleteXmlTag() { + Tag testTag = new Tag("testTag", "testOwner"); + Tag createdTag = tagRepository.index(testTag); + Channel channel = new Channel("testChannel", "testOwner", null, Arrays.asList(createdTag)); + cleanupTestTags = Arrays.asList(testTag); + + Channel createdChannel = channelRepository.index(channel); + tagRepository.deleteById(createdTag.getName()); + // verify the tag was deleted as expected + Assertions.assertNotEquals( + testTag, tagRepository.findById(testTag.getName()), "Failed to delete tag"); + + // verify the tag was deleted from channels as expected + Channel foundChannel = channelRepository.findById("testChannel").get(); + Assertions.assertTrue(foundChannel.getTags().isEmpty(), "Failed to remove tag from channel"); + + // verify the tag was deleted from all channels as expected + MultiValueMap params = new LinkedMultiValueMap(); + params.add("~tag", "testChannel"); + List chans = channelRepository.search(params).channels(); + Assertions.assertTrue(chans.isEmpty(), "Failed to remove tag from channel"); + + // channel clean up + channelRepository.deleteById(createdChannel.getName()); + } + + // helper operations to clean up tagrepoIT + + private List cleanupTestTags = Collections.emptyList(); + + @AfterEach + public void cleanup() { + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.set("~name", "*"); + channelRepository + .search(map) + .channels() + .forEach(c -> channelRepository.deleteById(c.getName())); + tagRepository.findAll().forEach(t -> tagRepository.deleteById(t.getName())); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/TagValidationIT.java b/src/test/java/org/phoebus/channelfinder/TagValidationIT.java index 987e5483..aa05276e 100644 --- a/src/test/java/org/phoebus/channelfinder/TagValidationIT.java +++ b/src/test/java/org/phoebus/channelfinder/TagValidationIT.java @@ -1,5 +1,10 @@ package org.phoebus.channelfinder; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -12,132 +17,110 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.web.server.ResponseStatusException; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.fail; - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WebMvcTest(TagManager.class) @WithMockUser(roles = "CF-ADMINS") @TestPropertySource(value = "classpath:application_test.properties") class TagValidationIT { - @Autowired - TagManager tagManager; - - @Autowired - ElasticConfig esService; - @Autowired - ChannelRepository channelRepository; - - /** - * Attempt to Tag request with null name - */ - @Test - void validateXmlTagRequestNullName() { - Tag testTag1 = new Tag(null, "testOwner"); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + @Autowired TagManager tagManager; + + @Autowired ElasticConfig esService; + @Autowired ChannelRepository channelRepository; + + /** Attempt to Tag request with null name */ + @Test + void validateXmlTagRequestNullName() { + Tag testTag1 = new Tag(null, "testOwner"); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with empty name */ + @Test + void validateXmlTagRequestEmptyName() { + Tag testTag1 = new Tag("", "testOwner"); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with null owner */ + @Test + void validateXmlTagRequestNullOwner() { + Tag testTag1 = new Tag("testTag1", null); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with empty owner */ + @Test + void validateXmlTagRequestEmptyOwner() { + Tag testTag1 = new Tag("testTag1", ""); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with a non existent channel */ + @Test + void validateXmlTagRequestFakeChannel() { + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(Arrays.asList(new Channel("Non-existent-channel"))); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with multiple non existent channels */ + @Test + void validateXmlTagRequestFakeChannels() { + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels( + Arrays.asList(new Channel("Non-existent-channel"), new Channel("Non-existent-channel"))); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with some existent and some non existent channels */ + @Test + void validateXmlTagRequestSomeFakeChannels() { + channelRepository.indexAll(Arrays.asList(new Channel("testChannel0", "testOwner"))); + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels( + Arrays.asList(new Channel("Non-existent-channel"), new Channel("testChannel0"))); + Assertions.assertThrows( + ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with valid parameters */ + @Test + void validateXmlTagRequest() { + Tag testTag1 = new Tag("testTag1", "testOwner"); + try { + tagManager.validateTagRequest(testTag1); + Assertions.assertTrue(true); + } catch (Exception e) { + fail("Failed to validate with valid parameters"); } - - /** - * Attempt to Tag request with empty name - */ - @Test - void validateXmlTagRequestEmptyName() { - Tag testTag1 = new Tag("", "testOwner"); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); + } + + /** Attempt to Tag request with other valid parameters */ + @Test + void validateXmlTagRequest2() { + channelRepository.indexAll(List.of(new Channel("testChannel0", "testOwner"))); + + Tag testTag1 = new Tag("testTag1", "testOwner"); + testTag1.setChannels(List.of(new Channel("testChannel0"))); + try { + tagManager.validateTagRequest(testTag1); + Assertions.assertTrue(true); + } catch (Exception e) { + fail("Failed to validate with valid parameters"); } - /** - * Attempt to Tag request with null owner - */ - @Test - void validateXmlTagRequestNullOwner() { - Tag testTag1 = new Tag("testTag1", null); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); - } - - /** - * Attempt to Tag request with empty owner - */ - @Test - void validateXmlTagRequestEmptyOwner() { - Tag testTag1 = new Tag("testTag1", ""); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); - } - - /** - * Attempt to Tag request with a non existent channel - */ - @Test - void validateXmlTagRequestFakeChannel() { - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(Arrays.asList(new Channel("Non-existent-channel"))); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); - } - - /** - * Attempt to Tag request with multiple non existent channels - */ - @Test - void validateXmlTagRequestFakeChannels() { - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels( - Arrays.asList(new Channel("Non-existent-channel"), - new Channel("Non-existent-channel"))); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); - } - - /** - * Attempt to Tag request with some existent and some non existent channels - */ - @Test - void validateXmlTagRequestSomeFakeChannels() { - channelRepository.indexAll(Arrays.asList(new Channel("testChannel0", "testOwner"))); - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels( - Arrays.asList(new Channel("Non-existent-channel"), - new Channel("testChannel0"))); - Assertions.assertThrows(ResponseStatusException.class, () -> tagManager.validateTagRequest(testTag1)); - } + channelRepository.deleteById("testChannel0"); + } - /** - * Attempt to Tag request with valid parameters - */ - @Test - void validateXmlTagRequest() { - Tag testTag1 = new Tag("testTag1", "testOwner"); - try { - tagManager.validateTagRequest(testTag1); - Assertions.assertTrue(true); - } catch (Exception e) { - fail("Failed to validate with valid parameters"); - } - } - - /** - * Attempt to Tag request with other valid parameters - */ - @Test - void validateXmlTagRequest2() { - channelRepository.indexAll(List.of(new Channel("testChannel0", "testOwner"))); - - Tag testTag1 = new Tag("testTag1", "testOwner"); - testTag1.setChannels(List.of(new Channel("testChannel0"))); - try { - tagManager.validateTagRequest(testTag1); - Assertions.assertTrue(true); - } catch (Exception e) { - fail("Failed to validate with valid parameters"); - } - - channelRepository.deleteById("testChannel0"); - } - @AfterAll - void tearDown() throws IOException { - ElasticConfigIT.teardown(esService); - } -} \ No newline at end of file + @AfterAll + void tearDown() throws IOException { + ElasticConfigIT.teardown(esService); + } +} diff --git a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderChannelsIT.java b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderChannelsIT.java index c47a518c..bc0925c7 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderChannelsIT.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderChannelsIT.java @@ -18,8 +18,11 @@ package org.phoebus.channelfinder.docker; -import com.fasterxml.jackson.databind.ObjectMapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.net.HttpURLConnection; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -29,17 +32,11 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.net.HttpURLConnection; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - /** - * Integration tests for ChannelFinder and Elasticsearch with focus on usage of - * {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. + * Integration tests for ChannelFinder and Elasticsearch with focus on usage of {@link + * org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.ChannelManager * @see org.phoebus.channelfinder.docker.ITTestFixture * @see org.phoebus.channelfinder.docker.ITUtil @@ -48,1319 +45,1530 @@ @Testcontainers public class ChannelFinderChannelsIT { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // requires - // elastic indices for ChannelFinder, ensured at start-up - // environment - // default ports, can be exposed differently externally to avoid interference with any running instance - // demo_auth enabled - // docker containers shared for tests - // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other tests - // each test uses multiple endpoints in ChannelFinder API - // see test QueryByPattern for list of channels which match given expressions - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API - // -------------------- - // Retrieve a Channel .../channels/ GET - // List Channels / Query by Pattern .../channels?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET - // Query Count .../channels/count?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET - // Query Combined .../channels/combined?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET - // Create / Replace Channel .../channels/ PUT - // Create / Replace Multiple Channels .../channels PUT - // Update Channel .../channels/ POST - // Update Channels .../channels POST - // Delete a Channel .../channels/ DELETE - // ------------------------------------------------------------------------------------------------ - - // test data - // channels c1 - c10, owner o1 - // channel c1, owner o2 - - static Channel channel_c1_owner_o1; - static Channel channel_c2_owner_o1; - static Channel channel_c3_owner_o1; - static Channel channel_c4_owner_o1; - static Channel channel_c5_owner_o1; - static Channel channel_c6_owner_o1; - static Channel channel_c7_owner_o1; - static Channel channel_c8_owner_o1; - static Channel channel_c9_owner_o1; - static Channel channel_c10_owner_o1; - - static Channel channel_c1_owner_o2; - - @Container - public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - - @BeforeAll - public static void setupObjects() { - channel_c1_owner_o1 = new Channel("c1", "o1"); - channel_c2_owner_o1 = new Channel("c2", "o1"); - channel_c3_owner_o1 = new Channel("c3", "o1"); - channel_c4_owner_o1 = new Channel("c4", "o1"); - channel_c5_owner_o1 = new Channel("c5", "o1"); - channel_c6_owner_o1 = new Channel("c6", "o1"); - channel_c7_owner_o1 = new Channel("c7", "o1"); - channel_c8_owner_o1 = new Channel("c8", "o1"); - channel_c9_owner_o1 = new Channel("c9", "o1"); - channel_c10_owner_o1 = new Channel("c10", "o1"); - - channel_c1_owner_o2 = new Channel("c1", "o2"); - } - - @AfterAll - public static void tearDownObjects() { - channel_c1_owner_o1 = null; - channel_c2_owner_o1 = null; - channel_c3_owner_o1 = null; - channel_c4_owner_o1 = null; - channel_c5_owner_o1 = null; - channel_c6_owner_o1 = null; - channel_c7_owner_o1 = null; - channel_c8_owner_o1 = null; - channel_c9_owner_o1 = null; - channel_c10_owner_o1 = null; - - channel_c1_owner_o2 = null; - } - - @AfterAll - public static void extractJacocoReport() { - // extract jacoco report from container file system - ITUtil.extractJacocoReport(ENVIRONMENT, - ITUtil.JACOCO_TARGET_PREFIX + ChannelFinderChannelsIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); - } - - @Test - void channelfinderUp() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // requires + // elastic indices for ChannelFinder, ensured at start-up + // environment + // default ports, can be exposed differently externally to avoid interference with + // any running instance + // demo_auth enabled + // docker containers shared for tests + // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other + // tests + // each test uses multiple endpoints in ChannelFinder API + // see test QueryByPattern for list of channels which match given expressions + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + // CHANNELFINDER API + // -------------------- + // Retrieve a Channel .../channels/ + // GET + // List Channels / Query by Pattern + // .../channels?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET + // Query Count + // .../channels/count?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET + // Query Combined + // .../channels/combined?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... GET + // Create / Replace Channel .../channels/ + // PUT + // Create / Replace Multiple Channels .../channels + // PUT + // Update Channel .../channels/ + // POST + // Update Channels .../channels + // POST + // Delete a Channel .../channels/ + // DELETE + // + // ------------------------------------------------------------------------------------------------ + + // test data + // channels c1 - c10, owner o1 + // channel c1, owner o2 + + static Channel channel_c1_owner_o1; + static Channel channel_c2_owner_o1; + static Channel channel_c3_owner_o1; + static Channel channel_c4_owner_o1; + static Channel channel_c5_owner_o1; + static Channel channel_c6_owner_o1; + static Channel channel_c7_owner_o1; + static Channel channel_c8_owner_o1; + static Channel channel_c9_owner_o1; + static Channel channel_c10_owner_o1; + + static Channel channel_c1_owner_o2; + + @Container public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); + + @BeforeAll + public static void setupObjects() { + channel_c1_owner_o1 = new Channel("c1", "o1"); + channel_c2_owner_o1 = new Channel("c2", "o1"); + channel_c3_owner_o1 = new Channel("c3", "o1"); + channel_c4_owner_o1 = new Channel("c4", "o1"); + channel_c5_owner_o1 = new Channel("c5", "o1"); + channel_c6_owner_o1 = new Channel("c6", "o1"); + channel_c7_owner_o1 = new Channel("c7", "o1"); + channel_c8_owner_o1 = new Channel("c8", "o1"); + channel_c9_owner_o1 = new Channel("c9", "o1"); + channel_c10_owner_o1 = new Channel("c10", "o1"); + + channel_c1_owner_o2 = new Channel("c1", "o2"); + } + + @AfterAll + public static void tearDownObjects() { + channel_c1_owner_o1 = null; + channel_c2_owner_o1 = null; + channel_c3_owner_o1 = null; + channel_c4_owner_o1 = null; + channel_c5_owner_o1 = null; + channel_c6_owner_o1 = null; + channel_c7_owner_o1 = null; + channel_c8_owner_o1 = null; + channel_c9_owner_o1 = null; + channel_c10_owner_o1 = null; + + channel_c1_owner_o2 = null; + } + + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + ITUtil.extractJacocoReport( + ENVIRONMENT, + ITUtil.JACOCO_TARGET_PREFIX + + ChannelFinderChannelsIT.class.getSimpleName() + + ITUtil.JACOCO_TARGET_SUFFIX); + } + + @Test + void channelfinderUp() { + try { + int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannelRetrieveCheck() { - // what - // check(s) for retrieve channel - // e.g. - // retrieve non-existing channel - - ITUtilChannels.assertRetrieveChannel("/c11", HttpURLConnection.HTTP_NOT_FOUND); - } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleChannelDeleteCheck() { - // what - // check(s) for delete channel - // e.g. - // remove non-existing channel - - try { - // might be both 401, 404 - // 401 UNAUTHORIZED - // 404 NOT_FOUND - - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.NONE, "/c11", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.USER, "/c11", HttpURLConnection.HTTP_NOT_FOUND); - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.ADMIN, "/c11", HttpURLConnection.HTTP_NOT_FOUND); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannelRetrieveCheck() { + // what + // check(s) for retrieve channel + // e.g. + // retrieve non-existing channel + + ITUtilChannels.assertRetrieveChannel("/c11", HttpURLConnection.HTTP_NOT_FOUND); + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleChannelDeleteCheck() { + // what + // check(s) for delete channel + // e.g. + // remove non-existing channel + + try { + // might be both 401, 404 + // 401 UNAUTHORIZED + // 404 NOT_FOUND + + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.NONE, "/c11", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.USER, "/c11", HttpURLConnection.HTTP_NOT_FOUND); + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.ADMIN, "/c11", HttpURLConnection.HTTP_NOT_FOUND); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannelCreateUpdateCheckJson() { - // what - // check(s) for create / update channel - // e.g. - // user without required role ChannelMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // properties - exists - // tags - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_incomplete2 = "{\"incomplete\""; - String json_incomplete3 = "{\"incomplete}"; - String json_incomplete4 = "{\"\"}"; - String json_incomplete5 = "{incomplete\"}"; - String json_incomplete6 = "\"incomplete\"}"; - String json_incomplete7 = "{"; - String json_incomplete8 = "}"; - String json_incomplete9 = "\""; - - String json_channel_c1_name_na = "{\"na\":\"c1\",\"owner\":\"o1\"}"; - String json_channel_c1_owner_ow = "{\"name\":\"c1\",\"ow\":\"o1\"}"; - - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_channel_c1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/c1", json_channel_c1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_channel_c1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel(AuthorizationChoice.ADMIN, "/t1", json_channel_c1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannelCreateUpdateCheckJson() { + // what + // check(s) for create / update channel + // e.g. + // user without required role ChannelMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // properties - exists + // tags - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_incomplete2 = "{\"incomplete\""; + String json_incomplete3 = "{\"incomplete}"; + String json_incomplete4 = "{\"\"}"; + String json_incomplete5 = "{incomplete\"}"; + String json_incomplete6 = "\"incomplete\"}"; + String json_incomplete7 = "{"; + String json_incomplete8 = "}"; + String json_incomplete9 = "\""; + + String json_channel_c1_name_na = "{\"na\":\"c1\",\"owner\":\"o1\"}"; + String json_channel_c1_owner_ow = "{\"name\":\"c1\",\"ow\":\"o1\"}"; + + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/c1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, + "/c1", + json_channel_c1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, + "/c1", + json_channel_c1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, + "/t1", + json_channel_c1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, + "/t1", + json_channel_c1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannelCreateUpdateCheck() { - // what - // check(s) for create / update channel - // e.g. - // user without required role ChannelMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // properties - exists - // tags - exists - - Channel channel_check = new Channel(); - - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.NONE, "/c1", channel_c1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.NONE, "/c1", channel_c1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.USER, "/c1", channel_c1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.USER, "/c1", channel_c1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - - channel_check.setName(null); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - - channel_check.setName(""); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - - channel_check.setName("asdf"); - channel_check.setOwner(null); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - - channel_check.setName("asdf"); - channel_check.setOwner(""); - - ITUtilChannels.assertCreateReplaceChannel(AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilChannels.assertUpdateChannel (AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannelCreateUpdateCheck() { + // what + // check(s) for create / update channel + // e.g. + // user without required role ChannelMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // properties - exists + // tags - exists + + Channel channel_check = new Channel(); + + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.NONE, + "/c1", + channel_c1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.NONE, + "/c1", + channel_c1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.USER, + "/c1", + channel_c1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.USER, + "/c1", + channel_c1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + + channel_check.setName(null); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + + channel_check.setName(""); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + + channel_check.setName("asdf"); + channel_check.setOwner(null); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + + channel_check.setName("asdf"); + channel_check.setOwner(""); + + ITUtilChannels.assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilChannels.assertUpdateChannel( + AuthorizationChoice.ADMIN, "/asdf", channel_check, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannel() { - // what - // user with required role ChannelMod - // create channel - // list, create channel, list, retrieve, delete (unauthorized), delete, list - - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); - - ITUtilChannels.assertCountChannels(1); - ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); - - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.NONE, "/c1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.USER, "/c1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilChannels.assertDeleteChannel(AuthorizationChoice.ADMIN, "/c1", HttpURLConnection.HTTP_OK); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannel() { + // what + // user with required role ChannelMod + // create channel + // list, create channel, list, retrieve, delete (unauthorized), delete, list + + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); + + ITUtilChannels.assertCountChannels(1); + ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); + + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.NONE, "/c1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.USER, "/c1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilChannels.assertDeleteChannel( + AuthorizationChoice.ADMIN, "/c1", HttpURLConnection.HTTP_OK); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannel2() { - // what - // create channels, one by one - // list, create channel * 2, list, retrieve, retrieve, delete, list, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannel2() { + // what + // create channels, one by one + // list, create channel * 2, list, retrieve, retrieve, delete, list, retrieve, delete, + // list - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2_owner_o1); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2_owner_o1); - ITUtilChannels.assertCountChannels(2); - ITUtilChannels.assertListChannels(2, - channel_c1_owner_o1, - channel_c2_owner_o1); + ITUtilChannels.assertCountChannels(2); + ITUtilChannels.assertListChannels(2, channel_c1_owner_o1, channel_c2_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertCountChannels(1); - ITUtilChannels.assertListChannels(1, channel_c2_owner_o1); + ITUtilChannels.assertCountChannels(1); + ITUtilChannels.assertListChannels(1, channel_c2_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); - ITUtilChannels.assertDeleteChannel("/c2"); + ITUtilChannels.assertDeleteChannel("/c2"); - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannel3RenameOwner() { - // what - // replace channel, rename channel - // list, create channel, list, retrieve, update, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannel3RenameOwner() { + // what + // replace channel, rename channel + // list, create channel, list, retrieve, update, retrieve, delete, list - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertCountChannels(1); - ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); + ITUtilChannels.assertCountChannels(1); + ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertUpdateChannel("/c1", channel_c1_owner_o2); + ITUtilChannels.assertUpdateChannel("/c1", channel_c1_owner_o2); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o2); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o2); - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannel4ReplaceNonExisting() { - // what - // replace non-existing channel - // list, update, list, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannel4ReplaceNonExisting() { + // what + // replace non-existing channel + // list, update, list, retrieve, delete, list - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilChannels.assertUpdateChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertUpdateChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertCountChannels(1); - ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); + ITUtilChannels.assertCountChannels(1); + ITUtilChannels.assertListChannels(1, channel_c1_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannelsCreateUpdateCheck() { - // what - // check(s) for create tag - // e.g. - // user without required role ChannelMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // properties - exists - // tags - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_channel_c1_name_na = "{\"na\":\"c1\",\"owner\":\"o1\"}"; - String json_channel_c1_owner_ow = "{\"name\":\"c1\",\"ow\":\"o1\"}"; - - ObjectMapper mapper = new ObjectMapper(); - - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - String json_multiple = "[" - + mapper.writeValueAsString(channel_c1_owner_o1) - + "," + mapper.writeValueAsString(channel_c2_owner_o1) - + "," + mapper.writeValueAsString(channel_c3_owner_o1) - + "," + mapper.writeValueAsString(channel_c4_owner_o1) - + "," + mapper.writeValueAsString(channel_c5_owner_o1) - + "," + mapper.writeValueAsString(channel_c6_owner_o1) - + "," + mapper.writeValueAsString(channel_c7_owner_o1) - + "," + mapper.writeValueAsString(channel_c8_owner_o1) - + "," + mapper.writeValueAsString(channel_c9_owner_o1) - + "," + mapper.writeValueAsString(channel_c10_owner_o1) - + "," + json_incomplete1 + "]"; - - ITUtilChannels.assertCreateReplaceMultipleChannels(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - json_multiple = "[" - + mapper.writeValueAsString(channel_c1_owner_o1) - + "," + mapper.writeValueAsString(channel_c2_owner_o1) - + "," + mapper.writeValueAsString(channel_c3_owner_o1) - + "," + mapper.writeValueAsString(channel_c4_owner_o1) - + "," + mapper.writeValueAsString(channel_c5_owner_o1) - + "," + mapper.writeValueAsString(channel_c6_owner_o1) - + "," + mapper.writeValueAsString(channel_c7_owner_o1) - + "," + mapper.writeValueAsString(channel_c8_owner_o1) - + "," + mapper.writeValueAsString(channel_c9_owner_o1) - + "," + mapper.writeValueAsString(channel_c10_owner_o1) - + "," + json_channel_c1_name_na + "]"; - - ITUtilChannels.assertCreateReplaceMultipleChannels(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - json_multiple = "[" - + mapper.writeValueAsString(channel_c1_owner_o1) - + "," + mapper.writeValueAsString(channel_c2_owner_o1) - + "," + mapper.writeValueAsString(channel_c3_owner_o1) - + "," + mapper.writeValueAsString(channel_c4_owner_o1) - + "," + mapper.writeValueAsString(channel_c5_owner_o1) - + "," + mapper.writeValueAsString(channel_c6_owner_o1) - + "," + mapper.writeValueAsString(channel_c7_owner_o1) - + "," + mapper.writeValueAsString(channel_c8_owner_o1) - + "," + mapper.writeValueAsString(channel_c9_owner_o1) - + "," + mapper.writeValueAsString(channel_c10_owner_o1) - + "," + json_channel_c1_owner_ow + "]"; - - ITUtilChannels.assertCreateReplaceMultipleChannels(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannelsCreateUpdateCheck() { + // what + // check(s) for create tag + // e.g. + // user without required role ChannelMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // properties - exists + // tags - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_channel_c1_name_na = "{\"na\":\"c1\",\"owner\":\"o1\"}"; + String json_channel_c1_owner_ow = "{\"name\":\"c1\",\"ow\":\"o1\"}"; + + ObjectMapper mapper = new ObjectMapper(); + + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + String json_multiple = + "[" + + mapper.writeValueAsString(channel_c1_owner_o1) + + "," + + mapper.writeValueAsString(channel_c2_owner_o1) + + "," + + mapper.writeValueAsString(channel_c3_owner_o1) + + "," + + mapper.writeValueAsString(channel_c4_owner_o1) + + "," + + mapper.writeValueAsString(channel_c5_owner_o1) + + "," + + mapper.writeValueAsString(channel_c6_owner_o1) + + "," + + mapper.writeValueAsString(channel_c7_owner_o1) + + "," + + mapper.writeValueAsString(channel_c8_owner_o1) + + "," + + mapper.writeValueAsString(channel_c9_owner_o1) + + "," + + mapper.writeValueAsString(channel_c10_owner_o1) + + "," + + json_incomplete1 + + "]"; + + ITUtilChannels.assertCreateReplaceMultipleChannels( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + json_multiple = + "[" + + mapper.writeValueAsString(channel_c1_owner_o1) + + "," + + mapper.writeValueAsString(channel_c2_owner_o1) + + "," + + mapper.writeValueAsString(channel_c3_owner_o1) + + "," + + mapper.writeValueAsString(channel_c4_owner_o1) + + "," + + mapper.writeValueAsString(channel_c5_owner_o1) + + "," + + mapper.writeValueAsString(channel_c6_owner_o1) + + "," + + mapper.writeValueAsString(channel_c7_owner_o1) + + "," + + mapper.writeValueAsString(channel_c8_owner_o1) + + "," + + mapper.writeValueAsString(channel_c9_owner_o1) + + "," + + mapper.writeValueAsString(channel_c10_owner_o1) + + "," + + json_channel_c1_name_na + + "]"; + + ITUtilChannels.assertCreateReplaceMultipleChannels( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + json_multiple = + "[" + + mapper.writeValueAsString(channel_c1_owner_o1) + + "," + + mapper.writeValueAsString(channel_c2_owner_o1) + + "," + + mapper.writeValueAsString(channel_c3_owner_o1) + + "," + + mapper.writeValueAsString(channel_c4_owner_o1) + + "," + + mapper.writeValueAsString(channel_c5_owner_o1) + + "," + + mapper.writeValueAsString(channel_c6_owner_o1) + + "," + + mapper.writeValueAsString(channel_c7_owner_o1) + + "," + + mapper.writeValueAsString(channel_c8_owner_o1) + + "," + + mapper.writeValueAsString(channel_c9_owner_o1) + + "," + + mapper.writeValueAsString(channel_c10_owner_o1) + + "," + + json_channel_c1_owner_ow + + "]"; + + ITUtilChannels.assertCreateReplaceMultipleChannels( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertUpdateChannels("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannels() { - // what - // create channels - // list, create channels (10), list, retrieve (10), delete (5), list, delete (5), list - - Channel[] channels_10 = new Channel[] { - channel_c1_owner_o1, - channel_c10_owner_o1, - channel_c2_owner_o1, - channel_c3_owner_o1, - channel_c4_owner_o1, - channel_c5_owner_o1, - channel_c6_owner_o1, - channel_c7_owner_o1, - channel_c8_owner_o1, - channel_c9_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannels() { + // what + // create channels + // list, create channels (10), list, retrieve (10), delete (5), list, delete (5), list + + Channel[] channels_10 = + new Channel[] { + channel_c1_owner_o1, + channel_c10_owner_o1, + channel_c2_owner_o1, + channel_c3_owner_o1, + channel_c4_owner_o1, + channel_c5_owner_o1, + channel_c6_owner_o1, + channel_c7_owner_o1, + channel_c8_owner_o1, + channel_c9_owner_o1 }; - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - ITUtilChannels.assertCreateReplaceMultipleChannels("", channels_10); - - ITUtilChannels.assertCountChannels(10); - ITUtilChannels.assertListChannels(10, channels_10); - - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c4", channel_c4_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c5", channel_c5_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c6", channel_c6_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c7", channel_c7_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c8", channel_c8_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c9", channel_c9_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c10", channel_c10_owner_o1); - - ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertDeleteChannel("/c2"); - ITUtilChannels.assertDeleteChannel("/c3"); - ITUtilChannels.assertDeleteChannel("/c4"); - ITUtilChannels.assertDeleteChannel("/c5"); - - ITUtilChannels.assertCountChannels(5); - ITUtilChannels.assertListChannels(5, - channel_c10_owner_o1, - channel_c6_owner_o1, - channel_c7_owner_o1, - channel_c8_owner_o1, - channel_c9_owner_o1); - - ITUtilChannels.assertDeleteChannel("/c6"); - ITUtilChannels.assertDeleteChannel("/c7"); - ITUtilChannels.assertDeleteChannel("/c8"); - ITUtilChannels.assertDeleteChannel("/c9"); - ITUtilChannels.assertDeleteChannel("/c10"); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + ITUtilChannels.assertCreateReplaceMultipleChannels("", channels_10); + + ITUtilChannels.assertCountChannels(10); + ITUtilChannels.assertListChannels(10, channels_10); + + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c4", channel_c4_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c5", channel_c5_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c6", channel_c6_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c7", channel_c7_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c8", channel_c8_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c9", channel_c9_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c10", channel_c10_owner_o1); + + ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c2"); + ITUtilChannels.assertDeleteChannel("/c3"); + ITUtilChannels.assertDeleteChannel("/c4"); + ITUtilChannels.assertDeleteChannel("/c5"); + + ITUtilChannels.assertCountChannels(5); + ITUtilChannels.assertListChannels( + 5, + channel_c10_owner_o1, + channel_c6_owner_o1, + channel_c7_owner_o1, + channel_c8_owner_o1, + channel_c9_owner_o1); + + ITUtilChannels.assertDeleteChannel("/c6"); + ITUtilChannels.assertDeleteChannel("/c7"); + ITUtilChannels.assertDeleteChannel("/c8"); + ITUtilChannels.assertDeleteChannel("/c9"); + ITUtilChannels.assertDeleteChannel("/c10"); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannels2ReplaceNonExisting() { - // what - // replace non-existing channels - // list, update channels (10), list, retrieve (10), delete (5), list, delete (5), list - - Channel[] channels_10 = new Channel[] { - channel_c1_owner_o1, - channel_c10_owner_o1, - channel_c2_owner_o1, - channel_c3_owner_o1, - channel_c4_owner_o1, - channel_c5_owner_o1, - channel_c6_owner_o1, - channel_c7_owner_o1, - channel_c8_owner_o1, - channel_c9_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannels2ReplaceNonExisting() { + // what + // replace non-existing channels + // list, update channels (10), list, retrieve (10), delete (5), list, delete (5), list + + Channel[] channels_10 = + new Channel[] { + channel_c1_owner_o1, + channel_c10_owner_o1, + channel_c2_owner_o1, + channel_c3_owner_o1, + channel_c4_owner_o1, + channel_c5_owner_o1, + channel_c6_owner_o1, + channel_c7_owner_o1, + channel_c8_owner_o1, + channel_c9_owner_o1 }; - try { - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - - ITUtilChannels.assertUpdateChannels("", channels_10); - - ITUtilChannels.assertCountChannels(10); - ITUtilChannels.assertListChannels(10, channels_10); - - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c4", channel_c4_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c5", channel_c5_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c6", channel_c6_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c7", channel_c7_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c8", channel_c8_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c9", channel_c9_owner_o1); - ITUtilChannels.assertRetrieveChannel("/c10", channel_c10_owner_o1); - - ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertDeleteChannel("/c2"); - ITUtilChannels.assertDeleteChannel("/c3"); - ITUtilChannels.assertDeleteChannel("/c4"); - ITUtilChannels.assertDeleteChannel("/c5"); - - ITUtilChannels.assertCountChannels(5); - ITUtilChannels.assertListChannels(5, - channel_c10_owner_o1, - channel_c6_owner_o1, - channel_c7_owner_o1, - channel_c8_owner_o1, - channel_c9_owner_o1); - - ITUtilChannels.assertDeleteChannel("/c6"); - ITUtilChannels.assertDeleteChannel("/c7"); - ITUtilChannels.assertDeleteChannel("/c8"); - ITUtilChannels.assertDeleteChannel("/c9"); - ITUtilChannels.assertDeleteChannel("/c10"); - - ITUtilChannels.assertCountChannels(0); - ITUtilChannels.assertListChannels(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + + ITUtilChannels.assertUpdateChannels("", channels_10); + + ITUtilChannels.assertCountChannels(10); + ITUtilChannels.assertListChannels(10, channels_10); + + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c4", channel_c4_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c5", channel_c5_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c6", channel_c6_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c7", channel_c7_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c8", channel_c8_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c9", channel_c9_owner_o1); + ITUtilChannels.assertRetrieveChannel("/c10", channel_c10_owner_o1); + + ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c2"); + ITUtilChannels.assertDeleteChannel("/c3"); + ITUtilChannels.assertDeleteChannel("/c4"); + ITUtilChannels.assertDeleteChannel("/c5"); + + ITUtilChannels.assertCountChannels(5); + ITUtilChannels.assertListChannels( + 5, + channel_c10_owner_o1, + channel_c6_owner_o1, + channel_c7_owner_o1, + channel_c8_owner_o1, + channel_c9_owner_o1); + + ITUtilChannels.assertDeleteChannel("/c6"); + ITUtilChannels.assertDeleteChannel("/c7"); + ITUtilChannels.assertDeleteChannel("/c8"); + ITUtilChannels.assertDeleteChannel("/c9"); + ITUtilChannels.assertDeleteChannel("/c10"); + + ITUtilChannels.assertCountChannels(0); + ITUtilChannels.assertListChannels(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. - */ - @Test - void handleChannels3QueryByPattern() { - // what - // query by pattern - // -------------------------------------------------------------------------------- - // set up test fixture - // test - // query by pattern - // combine search parameters and channels, properties, tags - // tear down test fixture - - // -------------------------------------------------------------------------------- - // set up test fixture - // -------------------------------------------------------------------------------- - - ITTestFixture.setup(); - - // -------------------------------------------------------------------------------- - // query by pattern - // -------------------------------------------------------------------------------- - // patterns - // ? single character - // * any number of characters - // search parameters - // keyword - // ~name - // ~tag - // propertyName - // pagination - // ~size - // ~from - // -------------------------------------------------------------------------------- - // query for pattern - // non-existing - // exact - // pagination - // regex, regex pagination - // or, or regex, or regex pagination - // not, not regex, not regex pagination, not or, not regex or, not or regex pagination - // combinations - // -------------------------------------------------------------------------------- - // channels (10) - // ABC:DEF-GHI:JKL:001 - // ABC:DEF-GHI:JKL:002 - // ABC:DEF-GHI:JKL:003 - // ABC:DEF-GHI:JKL:010 - // ABC:DEF-GHI:JKL:011 - // ABC:DEF-XYZ:JKL:001 - // ABC:DEF-XYZ:JKL:002 - // ABC:DEF-XYZ:JKL:003 - // ABC:DEF-XYZ:JKL:010 - // ABC:DEF-XYZ:JKL:011 - // properties (4) - // domain (10 channels, values - cryo, power) - // element (10 channels, values - source, initial, radio, magnet, supra) - // type (10 channels, values - read, write, readwrite) - // cell (10 channels, values - block1, block2, block3, block4, block5) - // tags (4) - // archived ( 4 channels) - // handle_this ( 3 channels) - // noteworthy (10 channels) - // not_used ( 0 channels) - // -------------------------------------------------------------------------------- - // note - // regex regex-like, not regex - // ? means 1 character, not 0 or 1 character - // ~from causes exception if used without ~size - // causes exception if not a number - // if negative, then handled as 0 - // ~size causes exception if negative number or not a number - // ~size&~from if result without (~from) considered as array of 10 elements (0,1,2,3,4 5 6,7,8,9), - // then ~from=2 means element 2, i.e. 3rd element - // ---------------------------------------------------------------------------- - // or property value, not channel name, not tag name - // ------------------------------------------------------------- - // propertyName=value1&propertyName=value - // search for propertyName with value1 or value2 - // may be used with regex - // may be used with pagination - // care to be taken in usage as expression becomes complicated - // ---------------------------------------------------------------------------- - // not tag name, property value, not channel name - // ------------------------------------------------------------- - // propertyName!=value1 - // ~tag!=value1 - // may be used with regex - // may be used with pagination - // care to be taken in usage as expression becomes complicated - // if property values are (1, 2, 3, 4, 5) - // with expression propertyName!=1&propertyName!=2 - // then result is all values - not 1 or not 2 - // -------------------------------------------------------------------------------- - // search for non-existing property or tag gives exception - // search for non-existing channel gives empty result - // -------------------------------------------------------------------------------- - // tests may expanded by (give possibilities for broader search) - // all properties not present on all channels - // channel names have different lengths - // characters need escaping - // -------------------------------------------------------------------------------- - - try { - // channels (all) - ITUtilChannels.assertCountChannels(ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels(10, ITTestFixture.channels_all_properties_tags); - - // channel (name) - // query for pattern - // non-existing - // exact - // ABC:DEF-GHI:JKL:001 - // ABC:DEF-GHI:JKL:002 - // ABC:DEF-GHI:JKL:003 - // ABC:DEF-GHI:JKL:010 - // ABC:DEF-GHI:JKL:011 - // ABC:DEF-XYZ:JKL:001 - // ABC:DEF-XYZ:JKL:002 - // ABC:DEF-XYZ:JKL:003 - // ABC:DEF-XYZ:JKL:010 - // ABC:DEF-XYZ:JKL:011 - // pagination - // regex, regex pagination - - ITUtilChannels.assertCountChannels("?~name=asdf", 0); - ITUtilChannels.assertListChannels("?~name=asdf", 0); - - ITUtilChannels.assertCountChannels("?~name=ABC:DEF-GHI:JKL:001", 1); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:001", ITTestFixture.channel_ghi001_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:002", ITTestFixture.channel_ghi002_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:003", ITTestFixture.channel_ghi003_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:010", ITTestFixture.channel_ghi010_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:011", ITTestFixture.channel_ghi011_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:001", ITTestFixture.channel_xyz001_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:002", ITTestFixture.channel_xyz002_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:003", ITTestFixture.channel_xyz003_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:010", ITTestFixture.channel_xyz010_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:011", ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?~name=*001", 2); - ITUtilChannels.assertListChannels("?~name=*001", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?~name=ABC:DEF-XYZ:JKL:01?", 2); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:01?", - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?~name=ABC:DEF-???:JKL:003", 2); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-???:JKL:003", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=0", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=0", 0); - - ITUtilChannels.assertCountChannels("?~size=5", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=5", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=100", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=100", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=3&~from=-1", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=3&~from=-1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - ITUtilChannels.assertCountChannels("?~size=3&~from=0", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=3&~from=0", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=3&~from=1", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=3&~from=1", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=3&~from=2", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=3&~from=2", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?~size=3&~from=3", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~size=3&~from=3", - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?~name=*1*&~size=4&~from=2", 6); - ITUtilChannels.assertListChannels("?~name=*1*&~size=4&~from=2", - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - // property name (domain) - // query for pattern - // non-existing - // exact - cryo, power - // regex, regex pagination - // or, or regex, or regex pagination - // not, not with regex, not with regex and pagination - ITUtilChannels.assertCountChannels("?domain=asdf", 0); - ITUtilChannels.assertListChannels("?domain=asdf", 0); - - ITUtilChannels.assertCountChannels("?domain=cryo", 5); - ITUtilChannels.assertListChannels("?domain=cryo", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=power", 5); - ITUtilChannels.assertListChannels("?domain=power", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=cry?", 5); - ITUtilChannels.assertListChannels("?domain=cry?", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=?????r?????", 0); - ITUtilChannels.assertListChannels("?domain=?????r?????", 0); - - ITUtilChannels.assertCountChannels("?domain=?r??", 5); - ITUtilChannels.assertListChannels("?domain=?r??", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=?r???", 0); - ITUtilChannels.assertListChannels("?domain=?r???", 0); - - ITUtilChannels.assertCountChannels("?domain=*a*", 0); - ITUtilChannels.assertListChannels("?domain=*a*", 0); - - ITUtilChannels.assertCountChannels("?domain=?ow*&~size=4&~from=2", 5); - ITUtilChannels.assertListChannels("?domain=?ow*&~size=4&~from=2", - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=cryo&domain=power", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?domain=cryo&domain=power", - ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?", 5); - ITUtilChannels.assertListChannels("?domain=*o&domain=asdf?", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?&~size=3", 5); - ITUtilChannels.assertListChannels("?domain=*o&domain=asdf?&~size=3", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?&~size=3&~from=1", 5); - ITUtilChannels.assertListChannels("?domain=*o&domain=asdf?&~size=3&~from=1", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags); - - ITUtilChannels.assertCountChannels("?domain!=cryo", 5); - ITUtilChannels.assertListChannels("?domain!=cryo", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain!=*r", 5); - ITUtilChannels.assertListChannels("?domain!=*r", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags); - - ITUtilChannels.assertCountChannels("?domain!=cryo&~size=4", 5); - ITUtilChannels.assertListChannels("?domain!=cryo&~size=4", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags); - - ITUtilChannels.assertCountChannels("?domain!=cryo&~size=4&~from=0", 5); - ITUtilChannels.assertListChannels("?domain!=cryo&~size=4&~from=0", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags); - - // property name (element) - // query for pattern - // non-existing - // exact - source, initial, radio, magnet, supra - // regex, regex pagination - // or, or regex, or regex pagination - // not, not regex, not regex pagination, not or, not regex or, not or regex pagination - ITUtilChannels.assertCountChannels("?element=asdf", 0); - ITUtilChannels.assertListChannels("?element=asdf", 0); - - ITUtilChannels.assertCountChannels("?element=source", 2); - ITUtilChannels.assertListChannels("?element=source", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?element=initial", 2); - ITUtilChannels.assertListChannels("?element=initial", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?element=radio", 2); - ITUtilChannels.assertListChannels("?element=radio", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?element=magnet", 2); - ITUtilChannels.assertListChannels("?element=magnet", - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_xyz010_properties_tags); - - ITUtilChannels.assertCountChannels("?element=supra", 2); - ITUtilChannels.assertListChannels("?element=supra", - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?element=*i?", 2); - ITUtilChannels.assertListChannels("?element=*i?", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?element=?i*", 0); - ITUtilChannels.assertListChannels("?element=?i*", 0); - - ITUtilChannels.assertCountChannels("?element=*a*&~size=2&~from=4", 8); - ITUtilChannels.assertListChannels("?element=*a*&~size=2&~from=4", - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?element=initial&element=radio&element=supra", 6); - ITUtilChannels.assertListChannels("?element=initial&element=radio&element=supra", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?element=rad?o&element=asdf?", 2); - ITUtilChannels.assertListChannels("?element=rad?o&element=asdf?", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?element=initial&element=radio&element=supra&~size=4", 6); - ITUtilChannels.assertListChannels("?element=initial&element=radio&element=supra&~size=4", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?element=initial&element=radio&element=supra&~size=4&~from=3", 6); - ITUtilChannels.assertListChannels("?element=initial&element=radio&element=supra&~size=4&~from=3", - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?element!=initial", 8); - ITUtilChannels.assertListChannels("?element!=initial", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?element!=source&element!=initial", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?element!=source&element!=initial", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?element!=source&element!=initial&~size=6", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?element!=source&element!=initial&~size=6", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?element!=source&element!=initial&~size=6&~from=5", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?element!=source&element!=initial&~size=6&~from=5", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - // property name (type) - // query for pattern - // non-existing - // exact - read, write, readwrite, regex - // regex, regex pagination - // or, or regex, or regex pagination - // not, not regex, not regex pagination, not or, not regex or, not or regex pagination - ITUtilChannels.assertCountChannels("?type=asdf", 0); - ITUtilChannels.assertListChannels("?type=asdf", 0); - - ITUtilChannels.assertCountChannels("?type=read", 4); - ITUtilChannels.assertListChannels("?type=read", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?type=write", 4); - ITUtilChannels.assertListChannels("?type=write", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?type=readwrite", 2); - ITUtilChannels.assertListChannels("?type=readwrite", - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?type=read*", 6); - ITUtilChannels.assertListChannels("?type=read*", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?type=*write", 6); - ITUtilChannels.assertListChannels("?type=*write", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?type=*r*", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?type=*r*", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?type=??a?&~size=2&~from=4", 4); - ITUtilChannels.assertListChannels("?type=??a?&~size=2&~from=4", 0); - - ITUtilChannels.assertCountChannels("?type=write&type=readwrite", 6); - ITUtilChannels.assertListChannels("?type=write&type=readwrite", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?type=writ?&type=writ*", 4); - ITUtilChannels.assertListChannels("?type=writ?&type=writ*", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?type=write&type=readwrite&~size=10", 6); - ITUtilChannels.assertListChannels("?type=write&type=readwrite&~size=10", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?type=write&type=readwrite&~size=10&~from=7", 6); - ITUtilChannels.assertListChannels("?type=write&type=readwrite&~size=10&~from=7", 0); - - ITUtilChannels.assertCountChannels("?type!=asdf", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?type!=asdf", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags); - - // property name (cell) - // query for pattern - // non-existing - // exact - block1, block2, block3, block4, block5 - // regex, regex pagination - // or, or regex, or regex pagination - // not, not regex, not regex pagination, not or, not regex or, not or regex pagination - ITUtilChannels.assertCountChannels("?cell=asdf", 0); - ITUtilChannels.assertListChannels("?cell=asdf", 0); - - ITUtilChannels.assertCountChannels("?cell=block1", 2); - ITUtilChannels.assertListChannels("?cell=block1", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block2", 2); - ITUtilChannels.assertListChannels("?cell=block2", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block3", 2); - ITUtilChannels.assertListChannels("?cell=block3", - ITTestFixture.channel_ghi003_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block4", 2); - ITUtilChannels.assertListChannels("?cell=block4", - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_xyz010_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block5", 2); - ITUtilChannels.assertListChannels("?cell=block5", - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block?", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?cell=block?", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=*2", 2); - ITUtilChannels.assertListChannels("?cell=*2", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block?&~size=5&~from=5", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?cell=block?&~size=5&~from=5", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags, - ITTestFixture.channel_xyz010_properties_tags, - ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block1&cell=block2", 4); - ITUtilChannels.assertListChannels("?cell=block1&cell=block2", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=*1&cell=*2", 4); - ITUtilChannels.assertListChannels("?cell=*1&cell=*2", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block1&cell=block2&cell=block2&~size=1", 4); - ITUtilChannels.assertListChannels("?cell=block1&cell=block2&cell=block2&~size=1", - ITTestFixture.channel_ghi001_properties_tags); - - ITUtilChannels.assertCountChannels("?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 4); - ITUtilChannels.assertListChannels("?cell=block1&cell=block2&cell=block2&~size=1&~from=0", - ITTestFixture.channel_ghi001_properties_tags); - - ITUtilChannels.assertCountChannels("?cell!=block", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?cell!=block", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?cell!=block?", 0); - ITUtilChannels.assertListChannels("?cell!=block?", 0); - - ITUtilChannels.assertCountChannels("?cell!=block*&size=10", 0); - ITUtilChannels.assertListChannels("?cell!=block*&size=10", 0); - - ITUtilChannels.assertCountChannels("?cell!=block?*&size=10&~from=0", 0); - ITUtilChannels.assertListChannels("?cell!=block?*&size=10&~from=0", 0); - - // tag (name) - // query for pattern - // non-existing - // exact - archived, handle_this, noteworthy, not_used - // regex, regex pagination - // not, not regex, not regex pagination - ITUtilChannels.assertCountChannels("?~tag=asdf", 0); - ITUtilChannels.assertListChannels("?~tag=asdf", 0); - - ITUtilChannels.assertCountChannels("?~tag=archived", 4); - ITUtilChannels.assertListChannels("?~tag=archived", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag=handle_this", 3); - ITUtilChannels.assertListChannels("?~tag=handle_this", - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag=noteworthy", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~tag=noteworthy", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag=not_used", 0); - ITUtilChannels.assertListChannels("?~tag=not_used", 0); - - ITUtilChannels.assertCountChannels("?~tag=*_*", 3); - ITUtilChannels.assertListChannels("?~tag=*_*", - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag=*i*", 6); - ITUtilChannels.assertListChannels("?~tag=*i*", - ITTestFixture.channel_ghi001_properties_tags, - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag=*i*&~size=4&~from=1", 6); - ITUtilChannels.assertListChannels("?~tag=*i*&~size=4&~from=1", - ITTestFixture.channel_ghi002_properties_tags, - ITTestFixture.channel_ghi010_properties_tags, - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag!=noteworthy", 0); - ITUtilChannels.assertListChannels("?~tag!=noteworthy", 0); - - ITUtilChannels.assertCountChannels("?~tag!=not_used", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~tag!=not_used", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags); - - ITUtilChannels.assertCountChannels("?~tag!=not_used&~size=10&~from=10", ITTestFixture.channels_all_properties_tags.length); - ITUtilChannels.assertListChannels("?~tag!=not_used&~size=10&~from=10", 0); - - // combinations - // query for pattern - // complex - // 3 properties - // 2 properties, 1 tag - // 2 properties, 1 tag, or - // 2 properties, 2 tags - // 2 properties, 1 tag, pagination - ITUtilChannels.assertCountChannels("?domain=cryo&element=source&cell=block1", 1); - ITUtilChannels.assertListChannels("?domain=cryo&element=source&cell=block1", ITTestFixture.channel_ghi001_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=power&type=write&~tag=noteworthy", 2); - ITUtilChannels.assertListChannels("?domain=power&type=write&~tag=noteworthy", - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=power&type=write&type=????write&~tag=noteworthy", 3); - ITUtilChannels.assertListChannels("?domain=power&type=write&type=????write&~tag=noteworthy", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags, - ITTestFixture.channel_xyz003_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 2); - ITUtilChannels.assertListChannels("?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - - ITUtilChannels.assertCountChannels("?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", 6); - ITUtilChannels.assertListChannels("?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", - ITTestFixture.channel_ghi011_properties_tags, - ITTestFixture.channel_xyz001_properties_tags, - ITTestFixture.channel_xyz002_properties_tags); - } catch (Exception e) { - fail(); - } - - // -------------------------------------------------------------------------------- - // tear down test fixture - // -------------------------------------------------------------------------------- - - ITTestFixture.tearDown(); + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#CHANNEL_RESOURCE_URI}. */ + @Test + void handleChannels3QueryByPattern() { + // what + // query by pattern + // -------------------------------------------------------------------------------- + // set up test fixture + // test + // query by pattern + // combine search parameters and channels, properties, tags + // tear down test fixture + + // -------------------------------------------------------------------------------- + // set up test fixture + // -------------------------------------------------------------------------------- + + ITTestFixture.setup(); + + // -------------------------------------------------------------------------------- + // query by pattern + // -------------------------------------------------------------------------------- + // patterns + // ? single character + // * any number of characters + // search parameters + // keyword + // ~name + // ~tag + // propertyName + // pagination + // ~size + // ~from + // -------------------------------------------------------------------------------- + // query for pattern + // non-existing + // exact + // pagination + // regex, regex pagination + // or, or regex, or regex pagination + // not, not regex, not regex pagination, not or, not regex or, not or regex pagination + // combinations + // -------------------------------------------------------------------------------- + // channels (10) + // ABC:DEF-GHI:JKL:001 + // ABC:DEF-GHI:JKL:002 + // ABC:DEF-GHI:JKL:003 + // ABC:DEF-GHI:JKL:010 + // ABC:DEF-GHI:JKL:011 + // ABC:DEF-XYZ:JKL:001 + // ABC:DEF-XYZ:JKL:002 + // ABC:DEF-XYZ:JKL:003 + // ABC:DEF-XYZ:JKL:010 + // ABC:DEF-XYZ:JKL:011 + // properties (4) + // domain (10 channels, values - cryo, power) + // element (10 channels, values - source, initial, radio, magnet, supra) + // type (10 channels, values - read, write, readwrite) + // cell (10 channels, values - block1, block2, block3, block4, block5) + // tags (4) + // archived ( 4 channels) + // handle_this ( 3 channels) + // noteworthy (10 channels) + // not_used ( 0 channels) + // -------------------------------------------------------------------------------- + // note + // regex regex-like, not regex + // ? means 1 character, not 0 or 1 character + // ~from causes exception if used without ~size + // causes exception if not a number + // if negative, then handled as 0 + // ~size causes exception if negative number or not a number + // ~size&~from if result without (~from) considered as array of 10 elements + // (0,1,2,3,4 5 6,7,8,9), + // then ~from=2 means element 2, i.e. 3rd element + // ---------------------------------------------------------------------------- + // or property value, not channel name, not tag name + // ------------------------------------------------------------- + // propertyName=value1&propertyName=value + // search for propertyName with value1 or value2 + // may be used with regex + // may be used with pagination + // care to be taken in usage as expression becomes complicated + // ---------------------------------------------------------------------------- + // not tag name, property value, not channel name + // ------------------------------------------------------------- + // propertyName!=value1 + // ~tag!=value1 + // may be used with regex + // may be used with pagination + // care to be taken in usage as expression becomes complicated + // if property values are (1, 2, 3, 4, 5) + // with expression propertyName!=1&propertyName!=2 + // then result is all values - not 1 or not 2 + // -------------------------------------------------------------------------------- + // search for non-existing property or tag gives exception + // search for non-existing channel gives empty result + // -------------------------------------------------------------------------------- + // tests may expanded by (give possibilities for broader search) + // all properties not present on all channels + // channel names have different lengths + // characters need escaping + // -------------------------------------------------------------------------------- + + try { + // channels (all) + ITUtilChannels.assertCountChannels(ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels(10, ITTestFixture.channels_all_properties_tags); + + // channel (name) + // query for pattern + // non-existing + // exact + // ABC:DEF-GHI:JKL:001 + // ABC:DEF-GHI:JKL:002 + // ABC:DEF-GHI:JKL:003 + // ABC:DEF-GHI:JKL:010 + // ABC:DEF-GHI:JKL:011 + // ABC:DEF-XYZ:JKL:001 + // ABC:DEF-XYZ:JKL:002 + // ABC:DEF-XYZ:JKL:003 + // ABC:DEF-XYZ:JKL:010 + // ABC:DEF-XYZ:JKL:011 + // pagination + // regex, regex pagination + + ITUtilChannels.assertCountChannels("?~name=asdf", 0); + ITUtilChannels.assertListChannels("?~name=asdf", 0); + + ITUtilChannels.assertCountChannels("?~name=ABC:DEF-GHI:JKL:001", 1); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:001", ITTestFixture.channel_ghi001_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:002", ITTestFixture.channel_ghi002_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:003", ITTestFixture.channel_ghi003_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:010", ITTestFixture.channel_ghi010_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:011", ITTestFixture.channel_ghi011_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:001", ITTestFixture.channel_xyz001_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:002", ITTestFixture.channel_xyz002_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:003", ITTestFixture.channel_xyz003_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:010", ITTestFixture.channel_xyz010_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:011", ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?~name=*001", 2); + ITUtilChannels.assertListChannels( + "?~name=*001", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?~name=ABC:DEF-XYZ:JKL:01?", 2); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:01?", + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?~name=ABC:DEF-???:JKL:003", 2); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-???:JKL:003", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=0", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?~size=0", 0); + + ITUtilChannels.assertCountChannels( + "?~size=5", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=5", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=100", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?~size=100", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=3&~from=-1", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=3&~from=-1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); + + ITUtilChannels.assertCountChannels( + "?~size=3&~from=0", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=3&~from=0", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=3&~from=1", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=3&~from=1", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=3&~from=2", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=3&~from=2", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~size=3&~from=3", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~size=3&~from=3", + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?~name=*1*&~size=4&~from=2", 6); + ITUtilChannels.assertListChannels( + "?~name=*1*&~size=4&~from=2", + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + // property name (domain) + // query for pattern + // non-existing + // exact - cryo, power + // regex, regex pagination + // or, or regex, or regex pagination + // not, not with regex, not with regex and pagination + ITUtilChannels.assertCountChannels("?domain=asdf", 0); + ITUtilChannels.assertListChannels("?domain=asdf", 0); + + ITUtilChannels.assertCountChannels("?domain=cryo", 5); + ITUtilChannels.assertListChannels( + "?domain=cryo", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=power", 5); + ITUtilChannels.assertListChannels( + "?domain=power", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=cry?", 5); + ITUtilChannels.assertListChannels( + "?domain=cry?", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=?????r?????", 0); + ITUtilChannels.assertListChannels("?domain=?????r?????", 0); + + ITUtilChannels.assertCountChannels("?domain=?r??", 5); + ITUtilChannels.assertListChannels( + "?domain=?r??", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=?r???", 0); + ITUtilChannels.assertListChannels("?domain=?r???", 0); + + ITUtilChannels.assertCountChannels("?domain=*a*", 0); + ITUtilChannels.assertListChannels("?domain=*a*", 0); + + ITUtilChannels.assertCountChannels("?domain=?ow*&~size=4&~from=2", 5); + ITUtilChannels.assertListChannels( + "?domain=?ow*&~size=4&~from=2", + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels( + "?domain=cryo&domain=power", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?domain=cryo&domain=power", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?", 5); + ITUtilChannels.assertListChannels( + "?domain=*o&domain=asdf?", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?&~size=3", 5); + ITUtilChannels.assertListChannels( + "?domain=*o&domain=asdf?&~size=3", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=*o&domain=asdf?&~size=3&~from=1", 5); + ITUtilChannels.assertListChannels( + "?domain=*o&domain=asdf?&~size=3&~from=1", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags); + + ITUtilChannels.assertCountChannels("?domain!=cryo", 5); + ITUtilChannels.assertListChannels( + "?domain!=cryo", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain!=*r", 5); + ITUtilChannels.assertListChannels( + "?domain!=*r", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags); + + ITUtilChannels.assertCountChannels("?domain!=cryo&~size=4", 5); + ITUtilChannels.assertListChannels( + "?domain!=cryo&~size=4", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags); + + ITUtilChannels.assertCountChannels("?domain!=cryo&~size=4&~from=0", 5); + ITUtilChannels.assertListChannels( + "?domain!=cryo&~size=4&~from=0", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags); + + // property name (element) + // query for pattern + // non-existing + // exact - source, initial, radio, magnet, supra + // regex, regex pagination + // or, or regex, or regex pagination + // not, not regex, not regex pagination, not or, not regex or, not or regex pagination + ITUtilChannels.assertCountChannels("?element=asdf", 0); + ITUtilChannels.assertListChannels("?element=asdf", 0); + + ITUtilChannels.assertCountChannels("?element=source", 2); + ITUtilChannels.assertListChannels( + "?element=source", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?element=initial", 2); + ITUtilChannels.assertListChannels( + "?element=initial", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?element=radio", 2); + ITUtilChannels.assertListChannels( + "?element=radio", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?element=magnet", 2); + ITUtilChannels.assertListChannels( + "?element=magnet", + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_xyz010_properties_tags); + + ITUtilChannels.assertCountChannels("?element=supra", 2); + ITUtilChannels.assertListChannels( + "?element=supra", + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?element=*i?", 2); + ITUtilChannels.assertListChannels( + "?element=*i?", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?element=?i*", 0); + ITUtilChannels.assertListChannels("?element=?i*", 0); + + ITUtilChannels.assertCountChannels("?element=*a*&~size=2&~from=4", 8); + ITUtilChannels.assertListChannels( + "?element=*a*&~size=2&~from=4", + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?element=initial&element=radio&element=supra", 6); + ITUtilChannels.assertListChannels( + "?element=initial&element=radio&element=supra", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?element=rad?o&element=asdf?", 2); + ITUtilChannels.assertListChannels( + "?element=rad?o&element=asdf?", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?element=initial&element=radio&element=supra&~size=4", 6); + ITUtilChannels.assertListChannels( + "?element=initial&element=radio&element=supra&~size=4", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels( + "?element=initial&element=radio&element=supra&~size=4&~from=3", 6); + ITUtilChannels.assertListChannels( + "?element=initial&element=radio&element=supra&~size=4&~from=3", + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?element!=initial", 8); + ITUtilChannels.assertListChannels( + "?element!=initial", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels( + "?element!=source&element!=initial", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?element!=source&element!=initial", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?element!=source&element!=initial&~size=6", + ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?element!=source&element!=initial&~size=6", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels( + "?element!=source&element!=initial&~size=6&~from=5", + ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?element!=source&element!=initial&~size=6&~from=5", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + // property name (type) + // query for pattern + // non-existing + // exact - read, write, readwrite, regex + // regex, regex pagination + // or, or regex, or regex pagination + // not, not regex, not regex pagination, not or, not regex or, not or regex pagination + ITUtilChannels.assertCountChannels("?type=asdf", 0); + ITUtilChannels.assertListChannels("?type=asdf", 0); + + ITUtilChannels.assertCountChannels("?type=read", 4); + ITUtilChannels.assertListChannels( + "?type=read", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?type=write", 4); + ITUtilChannels.assertListChannels( + "?type=write", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?type=readwrite", 2); + ITUtilChannels.assertListChannels( + "?type=readwrite", + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?type=read*", 6); + ITUtilChannels.assertListChannels( + "?type=read*", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?type=*write", 6); + ITUtilChannels.assertListChannels( + "?type=*write", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels( + "?type=*r*", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?type=*r*", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels("?type=??a?&~size=2&~from=4", 4); + ITUtilChannels.assertListChannels("?type=??a?&~size=2&~from=4", 0); + + ITUtilChannels.assertCountChannels("?type=write&type=readwrite", 6); + ITUtilChannels.assertListChannels( + "?type=write&type=readwrite", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?type=writ?&type=writ*", 4); + ITUtilChannels.assertListChannels( + "?type=writ?&type=writ*", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?type=write&type=readwrite&~size=10", 6); + ITUtilChannels.assertListChannels( + "?type=write&type=readwrite&~size=10", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?type=write&type=readwrite&~size=10&~from=7", 6); + ITUtilChannels.assertListChannels("?type=write&type=readwrite&~size=10&~from=7", 0); + + ITUtilChannels.assertCountChannels( + "?type!=asdf", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?type!=asdf", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags); + + // property name (cell) + // query for pattern + // non-existing + // exact - block1, block2, block3, block4, block5 + // regex, regex pagination + // or, or regex, or regex pagination + // not, not regex, not regex pagination, not or, not regex or, not or regex pagination + ITUtilChannels.assertCountChannels("?cell=asdf", 0); + ITUtilChannels.assertListChannels("?cell=asdf", 0); + + ITUtilChannels.assertCountChannels("?cell=block1", 2); + ITUtilChannels.assertListChannels( + "?cell=block1", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block2", 2); + ITUtilChannels.assertListChannels( + "?cell=block2", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block3", 2); + ITUtilChannels.assertListChannels( + "?cell=block3", + ITTestFixture.channel_ghi003_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block4", 2); + ITUtilChannels.assertListChannels( + "?cell=block4", + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_xyz010_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block5", 2); + ITUtilChannels.assertListChannels( + "?cell=block5", + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels( + "?cell=block?", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?cell=block?", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=*2", 2); + ITUtilChannels.assertListChannels( + "?cell=*2", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels( + "?cell=block?&~size=5&~from=5", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?cell=block?&~size=5&~from=5", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags, + ITTestFixture.channel_xyz010_properties_tags, + ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block1&cell=block2", 4); + ITUtilChannels.assertListChannels( + "?cell=block1&cell=block2", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=*1&cell=*2", 4); + ITUtilChannels.assertListChannels( + "?cell=*1&cell=*2", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block1&cell=block2&cell=block2&~size=1", 4); + ITUtilChannels.assertListChannels( + "?cell=block1&cell=block2&cell=block2&~size=1", + ITTestFixture.channel_ghi001_properties_tags); + + ITUtilChannels.assertCountChannels("?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 4); + ITUtilChannels.assertListChannels( + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", + ITTestFixture.channel_ghi001_properties_tags); + + ITUtilChannels.assertCountChannels( + "?cell!=block", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?cell!=block", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels("?cell!=block?", 0); + ITUtilChannels.assertListChannels("?cell!=block?", 0); + + ITUtilChannels.assertCountChannels("?cell!=block*&size=10", 0); + ITUtilChannels.assertListChannels("?cell!=block*&size=10", 0); + + ITUtilChannels.assertCountChannels("?cell!=block?*&size=10&~from=0", 0); + ITUtilChannels.assertListChannels("?cell!=block?*&size=10&~from=0", 0); + + // tag (name) + // query for pattern + // non-existing + // exact - archived, handle_this, noteworthy, not_used + // regex, regex pagination + // not, not regex, not regex pagination + ITUtilChannels.assertCountChannels("?~tag=asdf", 0); + ITUtilChannels.assertListChannels("?~tag=asdf", 0); + + ITUtilChannels.assertCountChannels("?~tag=archived", 4); + ITUtilChannels.assertListChannels( + "?~tag=archived", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?~tag=handle_this", 3); + ITUtilChannels.assertListChannels( + "?~tag=handle_this", + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~tag=noteworthy", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~tag=noteworthy", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels("?~tag=not_used", 0); + ITUtilChannels.assertListChannels("?~tag=not_used", 0); + + ITUtilChannels.assertCountChannels("?~tag=*_*", 3); + ITUtilChannels.assertListChannels( + "?~tag=*_*", + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?~tag=*i*", 6); + ITUtilChannels.assertListChannels( + "?~tag=*i*", + ITTestFixture.channel_ghi001_properties_tags, + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels("?~tag=*i*&~size=4&~from=1", 6); + ITUtilChannels.assertListChannels( + "?~tag=*i*&~size=4&~from=1", + ITTestFixture.channel_ghi002_properties_tags, + ITTestFixture.channel_ghi010_properties_tags, + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags); + + ITUtilChannels.assertCountChannels("?~tag!=noteworthy", 0); + ITUtilChannels.assertListChannels("?~tag!=noteworthy", 0); + + ITUtilChannels.assertCountChannels( + "?~tag!=not_used", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~tag!=not_used", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels( + "?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags); + + ITUtilChannels.assertCountChannels( + "?~tag!=not_used&~size=10&~from=10", ITTestFixture.channels_all_properties_tags.length); + ITUtilChannels.assertListChannels("?~tag!=not_used&~size=10&~from=10", 0); + + // combinations + // query for pattern + // complex + // 3 properties + // 2 properties, 1 tag + // 2 properties, 1 tag, or + // 2 properties, 2 tags + // 2 properties, 1 tag, pagination + ITUtilChannels.assertCountChannels("?domain=cryo&element=source&cell=block1", 1); + ITUtilChannels.assertListChannels( + "?domain=cryo&element=source&cell=block1", ITTestFixture.channel_ghi001_properties_tags); + + ITUtilChannels.assertCountChannels("?domain=power&type=write&~tag=noteworthy", 2); + ITUtilChannels.assertListChannels( + "?domain=power&type=write&~tag=noteworthy", + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels( + "?domain=power&type=write&type=????write&~tag=noteworthy", 3); + ITUtilChannels.assertListChannels( + "?domain=power&type=write&type=????write&~tag=noteworthy", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags, + ITTestFixture.channel_xyz003_properties_tags); + + ITUtilChannels.assertCountChannels( + "?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 2); + ITUtilChannels.assertListChannels( + "?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + + ITUtilChannels.assertCountChannels( + "?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", 6); + ITUtilChannels.assertListChannels( + "?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", + ITTestFixture.channel_ghi011_properties_tags, + ITTestFixture.channel_xyz001_properties_tags, + ITTestFixture.channel_xyz002_properties_tags); + } catch (Exception e) { + fail(); } + // -------------------------------------------------------------------------------- + // tear down test fixture + // -------------------------------------------------------------------------------- + + ITTestFixture.tearDown(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderIT.java b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderIT.java index 3dce271b..4c3a65a9 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderIT.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderIT.java @@ -18,102 +18,114 @@ package org.phoebus.channelfinder.docker; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.net.HttpURLConnection; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.testcontainers.containers.ComposeContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.net.HttpURLConnection; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - /** * Integration tests for ChannelFinder and Elasticsearch with focus on endpoints being available. * * @author Lars Johansson - * * @see ITUtil */ @Testcontainers class ChannelFinderIT { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // requires - // elastic indices for ChannelFinder, ensured at start-up - // environment - // default ports, can be exposed differently externally to avoid interference with any running instance - // demo_auth enabled - // docker containers shared for tests - // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other tests - // each test uses multiple endpoints in ChannelFinder API - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - - @Container - public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - - @AfterAll - public static void extractJacocoReport() { - // extract jacoco report from container file system - ITUtil.extractJacocoReport(ENVIRONMENT, - ITUtil.JACOCO_TARGET_PREFIX + ChannelFinderIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); - } + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // requires + // elastic indices for ChannelFinder, ensured at start-up + // environment + // default ports, can be exposed differently externally to avoid interference with + // any running instance + // demo_auth enabled + // docker containers shared for tests + // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other + // tests + // each test uses multiple endpoints in ChannelFinder API + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ - @Test - void channelfinderUp() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + @Container public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } - } - @Test - void channelfinderUpTags() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/tags"); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + ITUtil.extractJacocoReport( + ENVIRONMENT, + ITUtil.JACOCO_TARGET_PREFIX + + ChannelFinderIT.class.getSimpleName() + + ITUtil.JACOCO_TARGET_SUFFIX); + } + + @Test + void channelfinderUp() { + try { + int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - @Test - void channelfinderUpProperties() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/properties"); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + } + + @Test + void channelfinderUpTags() { + try { + int responseCode = + ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/tags"); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - @Test - void channelfinderUpChannels() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/channels"); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + } + + @Test + void channelfinderUpProperties() { + try { + int responseCode = + ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/properties"); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - @Test - void channelfinderUpScroll() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/scroll"); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + } + + @Test + void channelfinderUpChannels() { + try { + int responseCode = + ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/channels"); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } + } + @Test + void channelfinderUpScroll() { + try { + int responseCode = + ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER + "/resources/scroll"); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); + } + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderPropertiesIT.java b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderPropertiesIT.java index e91f85d3..cb0118e4 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderPropertiesIT.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderPropertiesIT.java @@ -18,8 +18,11 @@ package org.phoebus.channelfinder.docker; -import com.fasterxml.jackson.databind.ObjectMapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.net.HttpURLConnection; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -30,17 +33,11 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.net.HttpURLConnection; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - /** - * Integration tests for ChannelFinder and Elasticsearch with focus on usage of - * {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. + * Integration tests for ChannelFinder and Elasticsearch with focus on usage of {@link + * org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.PropertyManager * @see org.phoebus.channelfinder.docker.ITUtil * @see org.phoebus.channelfinder.docker.ITUtilProperties @@ -48,823 +45,936 @@ @Testcontainers class ChannelFinderPropertiesIT { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // requires - // elastic indices for ChannelFinder, ensured at start-up - // environment - // default ports, can be exposed differently externally to avoid interference with any running instance - // demo_auth enabled - // docker containers shared for tests - // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other tests - // each test uses multiple endpoints in ChannelFinder API - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API - // -------------------- - // Retrieve a Property .../properties/ GET - // List Properties .../properties GET - // Create/Replace a Property .../properties/ PUT - // Add Property to a Single Channel .../properties// PUT - // Create/Replace Properties .../properties PUT - // Add Property to Multiple Channels .../properties/ POST - // Add Multiple Properties .../properties POST - // Remove Property from Single Channel .../properties// DELETE - // Remove Property .../properties/ DELETE - // ------------------------------------------------------------------------------------------------ - - // test data - // properties p1 - p10, owner o1 - // property p1, owner o2 - - static Property property_p1_owner_o1; - static Property property_p2_owner_o1; - static Property property_p3_owner_o1; - static Property property_p4_owner_o1; - static Property property_p5_owner_o1; - static Property property_p6_owner_o1; - static Property property_p7_owner_o1; - static Property property_p8_owner_o1; - static Property property_p9_owner_o1; - static Property property_p10_owner_o1; - - static Property property_p1_owner_o2; - static Property property_p2_owner_o2; - static Property property_p3_owner_o2; - - @Container - public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - - @BeforeAll - public static void setupObjects() { - property_p1_owner_o1 = new Property("p1", "o1", null); - property_p2_owner_o1 = new Property("p2", "o1", null); - property_p3_owner_o1 = new Property("p3", "o1", null); - property_p4_owner_o1 = new Property("p4", "o1", null); - property_p5_owner_o1 = new Property("p5", "o1", null); - property_p6_owner_o1 = new Property("p6", "o1", null); - property_p7_owner_o1 = new Property("p7", "o1", null); - property_p8_owner_o1 = new Property("p8", "o1", null); - property_p9_owner_o1 = new Property("p9", "o1", null); - property_p10_owner_o1 = new Property("p10", "o1", null); - - property_p1_owner_o2 = new Property("p1", "o2", null); - property_p2_owner_o2 = new Property("p2", "o2", null); - property_p3_owner_o2 = new Property("p3", "o2", null); - } - - @AfterAll - public static void tearDownObjects() { - property_p1_owner_o1 = null; - property_p2_owner_o1 = null; - property_p3_owner_o1 = null; - property_p4_owner_o1 = null; - property_p5_owner_o1 = null; - property_p6_owner_o1 = null; - property_p7_owner_o1 = null; - property_p8_owner_o1 = null; - property_p9_owner_o1 = null; - property_p10_owner_o1 = null; - - property_p1_owner_o2 = null; - property_p2_owner_o2 = null; - property_p3_owner_o2 = null; - } - - @AfterAll - public static void extractJacocoReport() { - // extract jacoco report from container file system - ITUtil.extractJacocoReport(ENVIRONMENT, - ITUtil.JACOCO_TARGET_PREFIX + ChannelFinderPropertiesIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // requires + // elastic indices for ChannelFinder, ensured at start-up + // environment + // default ports, can be exposed differently externally to avoid interference with + // any running instance + // demo_auth enabled + // docker containers shared for tests + // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other + // tests + // each test uses multiple endpoints in ChannelFinder API + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + // CHANNELFINDER API + // -------------------- + // Retrieve a Property .../properties/ + // GET + // List Properties .../properties + // GET + // Create/Replace a Property .../properties/ + // PUT + // Add Property to a Single Channel .../properties// + // PUT + // Create/Replace Properties .../properties + // PUT + // Add Property to Multiple Channels .../properties/ + // POST + // Add Multiple Properties .../properties + // POST + // Remove Property from Single Channel .../properties// + // DELETE + // Remove Property .../properties/ + // DELETE + // + // ------------------------------------------------------------------------------------------------ + + // test data + // properties p1 - p10, owner o1 + // property p1, owner o2 + + static Property property_p1_owner_o1; + static Property property_p2_owner_o1; + static Property property_p3_owner_o1; + static Property property_p4_owner_o1; + static Property property_p5_owner_o1; + static Property property_p6_owner_o1; + static Property property_p7_owner_o1; + static Property property_p8_owner_o1; + static Property property_p9_owner_o1; + static Property property_p10_owner_o1; + + static Property property_p1_owner_o2; + static Property property_p2_owner_o2; + static Property property_p3_owner_o2; + + @Container public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); + + @BeforeAll + public static void setupObjects() { + property_p1_owner_o1 = new Property("p1", "o1", null); + property_p2_owner_o1 = new Property("p2", "o1", null); + property_p3_owner_o1 = new Property("p3", "o1", null); + property_p4_owner_o1 = new Property("p4", "o1", null); + property_p5_owner_o1 = new Property("p5", "o1", null); + property_p6_owner_o1 = new Property("p6", "o1", null); + property_p7_owner_o1 = new Property("p7", "o1", null); + property_p8_owner_o1 = new Property("p8", "o1", null); + property_p9_owner_o1 = new Property("p9", "o1", null); + property_p10_owner_o1 = new Property("p10", "o1", null); + + property_p1_owner_o2 = new Property("p1", "o2", null); + property_p2_owner_o2 = new Property("p2", "o2", null); + property_p3_owner_o2 = new Property("p3", "o2", null); + } + + @AfterAll + public static void tearDownObjects() { + property_p1_owner_o1 = null; + property_p2_owner_o1 = null; + property_p3_owner_o1 = null; + property_p4_owner_o1 = null; + property_p5_owner_o1 = null; + property_p6_owner_o1 = null; + property_p7_owner_o1 = null; + property_p8_owner_o1 = null; + property_p9_owner_o1 = null; + property_p10_owner_o1 = null; + + property_p1_owner_o2 = null; + property_p2_owner_o2 = null; + property_p3_owner_o2 = null; + } + + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + ITUtil.extractJacocoReport( + ENVIRONMENT, + ITUtil.JACOCO_TARGET_PREFIX + + ChannelFinderPropertiesIT.class.getSimpleName() + + ITUtil.JACOCO_TARGET_SUFFIX); + } + + @Test + void channelfinderUp() { + try { + int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - - @Test - void channelfinderUp() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handlePropertyRetrieveCheck() { + // what + // check(s) for retrieve tag + // e.g. + // retrieve non-existing property + + ITUtilProperties.assertRetrieveProperty("/p11", HttpURLConnection.HTTP_NOT_FOUND); + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handlePropertyRemoveCheck() { + // what + // check(s) for remove property + // e.g. + // remove non-existing property + + try { + // might be both 401, 404 + // 401 UNAUTHORIZED + // 404 NOT_FOUND + + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.NONE, "/p11", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.USER, "/p11", HttpURLConnection.HTTP_NOT_FOUND); + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.ADMIN, "/p11", HttpURLConnection.HTTP_NOT_FOUND); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handlePropertyRetrieveCheck() { - // what - // check(s) for retrieve tag - // e.g. - // retrieve non-existing property - - ITUtilProperties.assertRetrieveProperty("/p11", HttpURLConnection.HTTP_NOT_FOUND); + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handlePropertyCreateUpdateCheckJson() { + // what + // check(s) for create / update property + // e.g. + // user without required role PropertyMod + // content not ok + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_incomplete2 = "{\"incomplete\""; + String json_incomplete3 = "{\"incomplete}"; + String json_incomplete4 = "{\"\"}"; + String json_incomplete5 = "{incomplete\"}"; + String json_incomplete6 = "\"incomplete\"}"; + String json_incomplete7 = "{"; + String json_incomplete8 = "}"; + String json_incomplete9 = "\""; + + String json_property_p1_name_na = "{\"na\":\"p1\",\"owner\":\"o1\"}"; + String json_property_p1_owner_ow = "{\"name\":\"p1\",\"ow\":\"o1\"}"; + + String json_property_p1_channels_c1 = + "{\"name\":\"p1\",\"owner\":\"o1\",\"value\":null,\"channels\":[" + + "{\"name\":\"c1\",\"owner\":\"o1\",\"properties\":[{\"name\":\"p1\",\"owner\":\"o1\",\"value\":\"asdf\",\"channels\":[]}],\"tags\":[]}" + + "]}"; + + try { + ITUtilProperties.assertListProperties(0); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/p1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_channels_c1, + HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/p1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, + "/p1", + json_property_p1_channels_c1, + HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handlePropertyRemoveCheck() { - // what - // check(s) for remove property - // e.g. - // remove non-existing property - - try { - // might be both 401, 404 - // 401 UNAUTHORIZED - // 404 NOT_FOUND - - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.NONE, "/p11", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.USER, "/p11", HttpURLConnection.HTTP_NOT_FOUND); - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.ADMIN, "/p11", HttpURLConnection.HTTP_NOT_FOUND); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handlePropertyCreateUpdateCheck() { + // what + // check(s) for create / update property + // e.g. + // user without required role PropertyMod + // content not ok + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + Property property_check = new Property(); + + try { + ITUtilProperties.assertListProperties(0); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.NONE, + "/p1", + property_p1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.NONE, + "/p1", + property_p1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.USER, + "/p1", + property_p1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.USER, + "/p1", + property_p1_owner_o1, + HttpURLConnection.HTTP_UNAUTHORIZED); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + + property_check.setName(null); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + + property_check.setName(""); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + + property_check.setName("asdf"); + property_check.setOwner(null); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + + property_check.setName("asdf"); + property_check.setOwner(""); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handlePropertyCreateUpdateCheckJson() { - // what - // check(s) for create / update property - // e.g. - // user without required role PropertyMod - // content not ok - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_incomplete2 = "{\"incomplete\""; - String json_incomplete3 = "{\"incomplete}"; - String json_incomplete4 = "{\"\"}"; - String json_incomplete5 = "{incomplete\"}"; - String json_incomplete6 = "\"incomplete\"}"; - String json_incomplete7 = "{"; - String json_incomplete8 = "}"; - String json_incomplete9 = "\""; - - String json_property_p1_name_na = "{\"na\":\"p1\",\"owner\":\"o1\"}"; - String json_property_p1_owner_ow = "{\"name\":\"p1\",\"ow\":\"o1\"}"; - - String json_property_p1_channels_c1 = "{\"name\":\"p1\",\"owner\":\"o1\",\"value\":null,\"channels\":[" - + "{\"name\":\"c1\",\"owner\":\"o1\",\"properties\":[{\"name\":\"p1\",\"owner\":\"o1\",\"value\":\"asdf\",\"channels\":[]}],\"tags\":[]}" - + "]}"; - - try { - ITUtilProperties.assertListProperties(0); - - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_property_p1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_property_p1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/p1", json_property_p1_channels_c1, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_property_p1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_property_p1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/p1", json_property_p1_channels_c1, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty() { + // what + // user with required role PropertyMod + // create property + // list, create property, list, retrieve, delete (unauthorized), delete, list + + try { + ITUtilProperties.assertListProperties(0); + + ITUtilProperties.assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, "/t1", property_p1_owner_o1); + + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1?withChannels=true", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1?withChannels=false", property_p1_owner_o1); + + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.NONE, "/p1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.USER, "/p1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilProperties.assertRemoveProperty( + AuthorizationChoice.ADMIN, "/p1", HttpURLConnection.HTTP_OK); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handlePropertyCreateUpdateCheck() { - // what - // check(s) for create / update property - // e.g. - // user without required role PropertyMod - // content not ok - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - Property property_check = new Property(); - - try { - ITUtilProperties.assertListProperties(0); - - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.NONE, "/p1", property_p1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.NONE, "/p1", property_p1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.USER, "/p1", property_p1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.USER, "/p1", property_p1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty2() { + // what + // create properties, one by one + // list, create property * 2, list, retrieve, retrieve, delete, list, retrieve, delete, + // list - property_check.setName(null); + try { + ITUtilProperties.assertListProperties(0); - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertCreateReplaceProperty("/p2", property_p2_owner_o1); - property_check.setName(""); + ITUtilProperties.assertListProperties(2, property_p1_owner_o1, property_p2_owner_o1); - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); - property_check.setName("asdf"); - property_check.setOwner(null); + ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertListProperties(1, property_p2_owner_o1); - property_check.setName("asdf"); - property_check.setOwner(""); + ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); - ITUtilProperties.assertCreateReplaceProperty (AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilProperties.assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", property_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilProperties.assertRemoveProperty("/p2"); - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty() { - // what - // user with required role PropertyMod - // create property - // list, create property, list, retrieve, delete (unauthorized), delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty3RenameOwner() { + // what + // replace property, rename owner + // list, create property, list, retrieve, update, retrieve, delete, list - try { - ITUtilProperties.assertListProperties(0); + try { + ITUtilProperties.assertListProperties(0); - ITUtilProperties.assertCreateReplaceProperty(AuthorizationChoice.ADMIN, "/t1", property_p1_owner_o1); + ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1?withChannels=true", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1?withChannels=false", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.NONE, "/p1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.USER, "/p1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilProperties.assertRemoveProperty(AuthorizationChoice.ADMIN, "/p1", HttpURLConnection.HTTP_OK); + ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_owner_o2); - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } - } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty2() { - // what - // create properties, one by one - // list, create property * 2, list, retrieve, retrieve, delete, list, retrieve, delete, list - - try { - ITUtilProperties.assertListProperties(0); - - ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertCreateReplaceProperty("/p2", property_p2_owner_o1); - - ITUtilProperties.assertListProperties(2, - property_p1_owner_o1, - property_p2_owner_o1); - - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o2); - ITUtilProperties.assertRemoveProperty("/p1"); + ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertListProperties(1, - property_p2_owner_o1); - - ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); - - ITUtilProperties.assertRemoveProperty("/p2"); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty3RenameOwner() { - // what - // replace property, rename owner - // list, create property, list, retrieve, update, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty4ReplaceNonExisting() { + // what + // replace non-existing property + // list, update, list, retrieve, delete, list - try { - ITUtilProperties.assertListProperties(0); + try { + ITUtilProperties.assertListProperties(0); - ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_owner_o1); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_owner_o2); + ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o2); - - ITUtilProperties.assertRemoveProperty("/p1"); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty4ReplaceNonExisting() { - // what - // replace non-existing property - // list, update, list, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty5SingleChannel() { + // what + // add property to single channel + // clean start, create property, create channel, + // add property to single channel, + // list, retrieve + // remove property from single channel, + // delete channel, delete property, clean end - try { - ITUtilProperties.assertListProperties(0); + Channel channel_c1 = new Channel("c1", "o1"); - ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_owner_o1); + Property property_p1_value = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "asdf"); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + Channel channel_c1_properties = new Channel("c1", "o1"); + channel_c1_properties.addProperty(property_p1_value); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + Property property_p1_channels = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner()); + property_p1_channels.getChannels().add(channel_c1_properties); - ITUtilProperties.assertRemoveProperty("/p1"); + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } - } + ITUtilProperties.assertListProperties(0); - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty5SingleChannel() { - // what - // add property to single channel - // clean start, create property, create channel, - // add property to single channel, - // list, retrieve - // remove property from single channel, - // delete channel, delete property, clean end + ITUtilTags.assertListTags(0); - Channel channel_c1 = new Channel("c1", "o1"); + ITUtilChannels.assertListChannels(0); - Property property_p1_value = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "asdf"); + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- - Channel channel_c1_properties = new Channel("c1", "o1"); - channel_c1_properties.addProperty(property_p1_value); + ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); - Property property_p1_channels = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner()); - property_p1_channels.getChannels().add(channel_c1_properties); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertListProperties(0); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); - ITUtilTags.assertListTags(0); + ITUtilChannels.assertListChannels(1, channel_c1); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // complex tests, add property to single channel + // -------------------------------------------------------------------------------- - ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertAddPropertySingleChannel("/p1/c1", property_p1_value); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_channels); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); + ITUtilChannels.assertListChannels(1, channel_c1_properties); - ITUtilChannels.assertListChannels(1, channel_c1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_properties); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); + // -------------------------------------------------------------------------------- + // complex tests, remove property from single channel + // -------------------------------------------------------------------------------- - // -------------------------------------------------------------------------------- - // complex tests, add property to single channel - // -------------------------------------------------------------------------------- + ITUtilProperties.assertRemovePropertySingleChannel("/p1/c1"); - ITUtilProperties.assertAddPropertySingleChannel("/p1/c1", property_p1_value); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_channels); + ITUtilChannels.assertListChannels(1, channel_c1); - ITUtilChannels.assertListChannels(1, channel_c1_properties); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_properties); + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- - // -------------------------------------------------------------------------------- - // complex tests, remove property from single channel - // -------------------------------------------------------------------------------- + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilProperties.assertRemovePropertySingleChannel("/p1/c1"); + ITUtilChannels.assertListChannels(0); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilTags.assertListTags(0); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilChannels.assertListChannels(1, channel_c1); - - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertDeleteChannel("/c1"); - - ITUtilChannels.assertListChannels(0); - - ITUtilTags.assertListTags(0); - - ITUtilProperties.assertRemoveProperty("/p1"); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperty6MultipleChannels() { - // what - // add property to multiple channels - // clean start, create property, create channel(s), - // add property to multiple channel(s), - // list, retrieve - // delete property, delete channel(s), clean end + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperty6MultipleChannels() { + // what + // add property to multiple channels + // clean start, create property, create channel(s), + // add property to multiple channel(s), + // list, retrieve + // delete property, delete channel(s), clean end - Channel channel_c1 = new Channel("c1", "o1"); - Channel channel_c2 = new Channel("c2", "o1"); - Channel channel_c3 = new Channel("c3", "o1"); + Channel channel_c1 = new Channel("c1", "o1"); + Channel channel_c2 = new Channel("c2", "o1"); + Channel channel_c3 = new Channel("c3", "o1"); - Property property_p1_value1 = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "qwer"); - Property property_p1_value2 = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "asdf"); - Property property_p1_value3 = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "zxcv"); + Property property_p1_value1 = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "qwer"); + Property property_p1_value2 = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "asdf"); + Property property_p1_value3 = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), "zxcv"); - Channel channel_c1_properties = new Channel("c1", "o1"); - Channel channel_c2_properties = new Channel("c2", "o1"); - Channel channel_c3_properties = new Channel("c3", "o1"); - channel_c1_properties.addProperty(property_p1_value1); - channel_c2_properties.addProperty(property_p1_value2); - channel_c3_properties.addProperty(property_p1_value3); + Channel channel_c1_properties = new Channel("c1", "o1"); + Channel channel_c2_properties = new Channel("c2", "o1"); + Channel channel_c3_properties = new Channel("c3", "o1"); + channel_c1_properties.addProperty(property_p1_value1); + channel_c2_properties.addProperty(property_p1_value2); + channel_c3_properties.addProperty(property_p1_value3); - Property property_p1_channels = new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), null); - property_p1_channels.getChannels().add(channel_c1_properties); - property_p1_channels.getChannels().add(channel_c2_properties); - property_p1_channels.getChannels().add(channel_c3_properties); + Property property_p1_channels = + new Property(property_p1_owner_o1.getName(), property_p1_owner_o1.getOwner(), null); + property_p1_channels.getChannels().add(channel_c1_properties); + property_p1_channels.getChannels().add(channel_c2_properties); + property_p1_channels.getChannels().add(channel_c3_properties); - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- - ITUtilProperties.assertListProperties(0); + ITUtilProperties.assertListProperties(0); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- - ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertCreateReplaceProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); - ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2); - ITUtilChannels.assertCreateReplaceChannel("/c3", channel_c3); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); + ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2); + ITUtilChannels.assertCreateReplaceChannel("/c3", channel_c3); - ITUtilChannels.assertListChannels(3, - channel_c1, - channel_c2, - channel_c3); + ITUtilChannels.assertListChannels(3, channel_c1, channel_c2, channel_c3); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3); - // -------------------------------------------------------------------------------- - // complex tests, add property to multiple channels - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // complex tests, add property to multiple channels + // -------------------------------------------------------------------------------- - ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_channels); + ITUtilProperties.assertAddPropertyMultipleChannels("/p1", property_p1_channels); - ITUtilProperties.assertListProperties(1, property_p1_owner_o1); + ITUtilProperties.assertListProperties(1, property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_channels); + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_channels); - ITUtilChannels.assertListChannels(3, - channel_c1_properties, - channel_c2_properties, - channel_c3_properties); + ITUtilChannels.assertListChannels( + 3, channel_c1_properties, channel_c2_properties, channel_c3_properties); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_properties); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_properties); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_properties); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_properties); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_properties); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_properties); - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- - ITUtilChannels.assertDeleteChannel("/c3"); - ITUtilChannels.assertDeleteChannel("/c2"); - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c3"); + ITUtilChannels.assertDeleteChannel("/c2"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilProperties.assertRemoveProperty("/p1"); + ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handlePropertiesCreateUpdateCheck() { - // what - // check(s) for create properties - // e.g. - // user without required role PropertyMod - // content not ok - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_property_p1_name_na = "{\"na\":\"p1\",\"owner\":\"o1\"}"; - String json_property_p1_owner_ow = "{\"name\":\"p1\",\"ow\":\"o1\"}"; - - ObjectMapper mapper = new ObjectMapper(); - - try { - ITUtilProperties.assertListProperties(0); - - String json_multiple = "[" - + mapper.writeValueAsString(property_p1_owner_o1) - + "," + mapper.writeValueAsString(property_p2_owner_o1) - + "," + mapper.writeValueAsString(property_p3_owner_o1) - + "," + mapper.writeValueAsString(property_p4_owner_o1) - + "," + mapper.writeValueAsString(property_p5_owner_o1) - + "," + mapper.writeValueAsString(property_p6_owner_o1) - + "," + mapper.writeValueAsString(property_p7_owner_o1) - + "," + mapper.writeValueAsString(property_p8_owner_o1) - + "," + mapper.writeValueAsString(property_p9_owner_o1) - + "," + mapper.writeValueAsString(property_p10_owner_o1) - + "," + json_incomplete1 + "]"; - - ITUtilProperties.assertCreateReplaceProperties(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilProperties.assertAddMultipleProperties("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - json_multiple = "[" - + mapper.writeValueAsString(property_p1_owner_o1) - + "," + mapper.writeValueAsString(property_p2_owner_o1) - + "," + mapper.writeValueAsString(property_p3_owner_o1) - + "," + mapper.writeValueAsString(property_p4_owner_o1) - + "," + mapper.writeValueAsString(property_p5_owner_o1) - + "," + mapper.writeValueAsString(property_p6_owner_o1) - + "," + mapper.writeValueAsString(property_p7_owner_o1) - + "," + mapper.writeValueAsString(property_p8_owner_o1) - + "," + mapper.writeValueAsString(property_p9_owner_o1) - + "," + mapper.writeValueAsString(property_p10_owner_o1) - + "," + json_property_p1_name_na + "]"; - - ITUtilProperties.assertCreateReplaceProperties(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - ITUtilProperties.assertAddMultipleProperties("", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - json_multiple = "[" - + mapper.writeValueAsString(property_p1_owner_o1) - + "," + mapper.writeValueAsString(property_p2_owner_o1) - + "," + mapper.writeValueAsString(property_p3_owner_o1) - + "," + mapper.writeValueAsString(property_p4_owner_o1) - + "," + mapper.writeValueAsString(property_p5_owner_o1) - + "," + mapper.writeValueAsString(property_p6_owner_o1) - + "," + mapper.writeValueAsString(property_p7_owner_o1) - + "," + mapper.writeValueAsString(property_p8_owner_o1) - + "," + mapper.writeValueAsString(property_p9_owner_o1) - + "," + mapper.writeValueAsString(property_p10_owner_o1) - + "," + json_property_p1_owner_ow + "]"; - - ITUtilProperties.assertCreateReplaceProperties(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilProperties.assertAddMultipleProperties("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handlePropertiesCreateUpdateCheck() { + // what + // check(s) for create properties + // e.g. + // user without required role PropertyMod + // content not ok + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_property_p1_name_na = "{\"na\":\"p1\",\"owner\":\"o1\"}"; + String json_property_p1_owner_ow = "{\"name\":\"p1\",\"ow\":\"o1\"}"; + + ObjectMapper mapper = new ObjectMapper(); + + try { + ITUtilProperties.assertListProperties(0); + + String json_multiple = + "[" + + mapper.writeValueAsString(property_p1_owner_o1) + + "," + + mapper.writeValueAsString(property_p2_owner_o1) + + "," + + mapper.writeValueAsString(property_p3_owner_o1) + + "," + + mapper.writeValueAsString(property_p4_owner_o1) + + "," + + mapper.writeValueAsString(property_p5_owner_o1) + + "," + + mapper.writeValueAsString(property_p6_owner_o1) + + "," + + mapper.writeValueAsString(property_p7_owner_o1) + + "," + + mapper.writeValueAsString(property_p8_owner_o1) + + "," + + mapper.writeValueAsString(property_p9_owner_o1) + + "," + + mapper.writeValueAsString(property_p10_owner_o1) + + "," + + json_incomplete1 + + "]"; + + ITUtilProperties.assertCreateReplaceProperties( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertAddMultipleProperties( + "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + json_multiple = + "[" + + mapper.writeValueAsString(property_p1_owner_o1) + + "," + + mapper.writeValueAsString(property_p2_owner_o1) + + "," + + mapper.writeValueAsString(property_p3_owner_o1) + + "," + + mapper.writeValueAsString(property_p4_owner_o1) + + "," + + mapper.writeValueAsString(property_p5_owner_o1) + + "," + + mapper.writeValueAsString(property_p6_owner_o1) + + "," + + mapper.writeValueAsString(property_p7_owner_o1) + + "," + + mapper.writeValueAsString(property_p8_owner_o1) + + "," + + mapper.writeValueAsString(property_p9_owner_o1) + + "," + + mapper.writeValueAsString(property_p10_owner_o1) + + "," + + json_property_p1_name_na + + "]"; + + ITUtilProperties.assertCreateReplaceProperties( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + ITUtilProperties.assertAddMultipleProperties( + "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + json_multiple = + "[" + + mapper.writeValueAsString(property_p1_owner_o1) + + "," + + mapper.writeValueAsString(property_p2_owner_o1) + + "," + + mapper.writeValueAsString(property_p3_owner_o1) + + "," + + mapper.writeValueAsString(property_p4_owner_o1) + + "," + + mapper.writeValueAsString(property_p5_owner_o1) + + "," + + mapper.writeValueAsString(property_p6_owner_o1) + + "," + + mapper.writeValueAsString(property_p7_owner_o1) + + "," + + mapper.writeValueAsString(property_p8_owner_o1) + + "," + + mapper.writeValueAsString(property_p9_owner_o1) + + "," + + mapper.writeValueAsString(property_p10_owner_o1) + + "," + + json_property_p1_owner_ow + + "]"; + + ITUtilProperties.assertCreateReplaceProperties( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertAddMultipleProperties( + "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperties() { - // what - // create properties - // list, create properties (10), list, retrieve (10), delete (5), list, delete (5), list - - Property[] properties_10 = new Property[] { - property_p1_owner_o1, - property_p2_owner_o1, - property_p3_owner_o1, - property_p4_owner_o1, - property_p5_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1, - property_p10_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperties() { + // what + // create properties + // list, create properties (10), list, retrieve (10), delete (5), list, delete (5), list + + Property[] properties_10 = + new Property[] { + property_p1_owner_o1, + property_p2_owner_o1, + property_p3_owner_o1, + property_p4_owner_o1, + property_p5_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1, + property_p10_owner_o1 }; - try { - ITUtilProperties.assertListProperties(0); - - ITUtilProperties.assertCreateReplaceProperties("", properties_10); - - ITUtilProperties.assertListProperties(10, - property_p1_owner_o1, - property_p10_owner_o1, - property_p2_owner_o1, - property_p3_owner_o1, - property_p4_owner_o1, - property_p5_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1); - - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p3", property_p3_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p4", property_p4_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p5", property_p5_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p6", property_p6_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p7", property_p7_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p8", property_p8_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p9", property_p9_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p10", property_p10_owner_o1); - - ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertRemoveProperty("/p2"); - ITUtilProperties.assertRemoveProperty("/p3"); - ITUtilProperties.assertRemoveProperty("/p4"); - ITUtilProperties.assertRemoveProperty("/p5"); - - ITUtilProperties.assertListProperties(5, - property_p10_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1); - - ITUtilProperties.assertRemoveProperty("/p6"); - ITUtilProperties.assertRemoveProperty("/p7"); - ITUtilProperties.assertRemoveProperty("/p8"); - ITUtilProperties.assertRemoveProperty("/p9"); - ITUtilProperties.assertRemoveProperty("/p10"); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilProperties.assertListProperties(0); + + ITUtilProperties.assertCreateReplaceProperties("", properties_10); + + ITUtilProperties.assertListProperties( + 10, + property_p1_owner_o1, + property_p10_owner_o1, + property_p2_owner_o1, + property_p3_owner_o1, + property_p4_owner_o1, + property_p5_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1); + + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p3", property_p3_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p4", property_p4_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p5", property_p5_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p6", property_p6_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p7", property_p7_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p8", property_p8_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p9", property_p9_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p10", property_p10_owner_o1); + + ITUtilProperties.assertRemoveProperty("/p1"); + ITUtilProperties.assertRemoveProperty("/p2"); + ITUtilProperties.assertRemoveProperty("/p3"); + ITUtilProperties.assertRemoveProperty("/p4"); + ITUtilProperties.assertRemoveProperty("/p5"); + + ITUtilProperties.assertListProperties( + 5, + property_p10_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1); + + ITUtilProperties.assertRemoveProperty("/p6"); + ITUtilProperties.assertRemoveProperty("/p7"); + ITUtilProperties.assertRemoveProperty("/p8"); + ITUtilProperties.assertRemoveProperty("/p9"); + ITUtilProperties.assertRemoveProperty("/p10"); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleProperties2ReplaceNonExisting() { - // what - // replace non-existing properties - // list, update properties (10), list, retrieve (10), delete (5), list, delete (5), list - - Property[] properties_10 = new Property[] { - property_p1_owner_o1, - property_p2_owner_o1, - property_p3_owner_o1, - property_p4_owner_o1, - property_p5_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1, - property_p10_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleProperties2ReplaceNonExisting() { + // what + // replace non-existing properties + // list, update properties (10), list, retrieve (10), delete (5), list, delete (5), list + + Property[] properties_10 = + new Property[] { + property_p1_owner_o1, + property_p2_owner_o1, + property_p3_owner_o1, + property_p4_owner_o1, + property_p5_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1, + property_p10_owner_o1 }; - try { - ITUtilProperties.assertListProperties(0); - - ITUtilProperties.assertAddMultipleProperties("", properties_10); - - ITUtilProperties.assertListProperties(10, - property_p1_owner_o1, - property_p10_owner_o1, - property_p2_owner_o1, - property_p3_owner_o1, - property_p4_owner_o1, - property_p5_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1); - - ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p3", property_p3_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p4", property_p4_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p5", property_p5_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p6", property_p6_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p7", property_p7_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p8", property_p8_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p9", property_p9_owner_o1); - ITUtilProperties.assertRetrieveProperty("/p10", property_p10_owner_o1); - - ITUtilProperties.assertRemoveProperty("/p1"); - ITUtilProperties.assertRemoveProperty("/p2"); - ITUtilProperties.assertRemoveProperty("/p3"); - ITUtilProperties.assertRemoveProperty("/p4"); - ITUtilProperties.assertRemoveProperty("/p5"); - - ITUtilProperties.assertListProperties(5, - property_p10_owner_o1, - property_p6_owner_o1, - property_p7_owner_o1, - property_p8_owner_o1, - property_p9_owner_o1); - - ITUtilProperties.assertRemoveProperty("/p6"); - ITUtilProperties.assertRemoveProperty("/p7"); - ITUtilProperties.assertRemoveProperty("/p8"); - ITUtilProperties.assertRemoveProperty("/p9"); - ITUtilProperties.assertRemoveProperty("/p10"); - - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilProperties.assertListProperties(0); + + ITUtilProperties.assertAddMultipleProperties("", properties_10); + + ITUtilProperties.assertListProperties( + 10, + property_p1_owner_o1, + property_p10_owner_o1, + property_p2_owner_o1, + property_p3_owner_o1, + property_p4_owner_o1, + property_p5_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1); + + ITUtilProperties.assertRetrieveProperty("/p1", property_p1_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p2", property_p2_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p3", property_p3_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p4", property_p4_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p5", property_p5_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p6", property_p6_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p7", property_p7_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p8", property_p8_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p9", property_p9_owner_o1); + ITUtilProperties.assertRetrieveProperty("/p10", property_p10_owner_o1); + + ITUtilProperties.assertRemoveProperty("/p1"); + ITUtilProperties.assertRemoveProperty("/p2"); + ITUtilProperties.assertRemoveProperty("/p3"); + ITUtilProperties.assertRemoveProperty("/p4"); + ITUtilProperties.assertRemoveProperty("/p5"); + + ITUtilProperties.assertListProperties( + 5, + property_p10_owner_o1, + property_p6_owner_o1, + property_p7_owner_o1, + property_p8_owner_o1, + property_p9_owner_o1); + + ITUtilProperties.assertRemoveProperty("/p6"); + ITUtilProperties.assertRemoveProperty("/p7"); + ITUtilProperties.assertRemoveProperty("/p8"); + ITUtilProperties.assertRemoveProperty("/p9"); + ITUtilProperties.assertRemoveProperty("/p10"); + + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderScrollIT.java b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderScrollIT.java index ea60d7ee..4132a949 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderScrollIT.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderScrollIT.java @@ -18,6 +18,10 @@ package org.phoebus.channelfinder.docker; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.net.HttpURLConnection; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.phoebus.channelfinder.entity.Scroll; @@ -25,17 +29,11 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.net.HttpURLConnection; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - /** - * Integration tests for ChannelFinder and Elasticsearch with focus on usage of - * {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. + * Integration tests for ChannelFinder and Elasticsearch with focus on usage of {@link + * org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.ChannelScroll * @see org.phoebus.channelfinder.docker.ITUtil * @see org.phoebus.channelfinder.docker.ITUtilScroll @@ -43,430 +41,603 @@ @Testcontainers class ChannelFinderScrollIT { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // requires - // elastic indices for ChannelFinder, ensured at start-up - // environment - // default ports, can be exposed differently externally to avoid interference with any running instance - // demo_auth enabled - // docker containers shared for tests - // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other tests - // each test uses multiple endpoints in ChannelFinder API - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - - @Container - public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - - @AfterAll - public static void extractJacocoReport() { - // extract jacoco report from container file system - ITUtil.extractJacocoReport(ENVIRONMENT, - ITUtil.JACOCO_TARGET_PREFIX + ChannelFinderScrollIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // requires + // elastic indices for ChannelFinder, ensured at start-up + // environment + // default ports, can be exposed differently externally to avoid interference with + // any running instance + // demo_auth enabled + // docker containers shared for tests + // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other + // tests + // each test uses multiple endpoints in ChannelFinder API + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + + @Container public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); + + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + ITUtil.extractJacocoReport( + ENVIRONMENT, + ITUtil.JACOCO_TARGET_PREFIX + + ChannelFinderScrollIT.class.getSimpleName() + + ITUtil.JACOCO_TARGET_SUFFIX); + } + + @Test + void channelfinderUp() { + try { + int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - - @Test - void channelfinderUp() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. */ + @Test + void handleScrollQueryChannels() { + // what + // check scroll + + try { + ITUtilScroll.assertQueryChannels("?foo123", 0); + ITUtilScroll.assertQueryChannels("?domain=cryo123", 0); + ITUtilScroll.assertQueryChannels("?~tag=archived123", 0); + ITUtilScroll.assertQueryChannels("?~name=*001123", 0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. - */ - @Test - void handleScrollQueryChannels() { - // what - // check scroll - - try { - ITUtilScroll.assertQueryChannels("?foo123", 0); - ITUtilScroll.assertQueryChannels("?domain=cryo123", 0); - ITUtilScroll.assertQueryChannels("?~tag=archived123", 0); - ITUtilScroll.assertQueryChannels("?~name=*001123", 0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. */ + @Test + void handleScrollContinueChannelsQuery() { + // what + // check scroll + + try { + ITUtilScroll.assertContinueChannelsQuery("/foo", 0); + ITUtilScroll.assertContinueChannelsQuery("/123", 0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. - */ - @Test - void handleScrollContinueChannelsQuery() { - // what - // check scroll - - try { - ITUtilScroll.assertContinueChannelsQuery("/foo", 0); - ITUtilScroll.assertContinueChannelsQuery("/123", 0); - } catch (Exception e) { - fail(); - } + } + + /** + * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. + * + * @see ChannelFinderChannelsIT#handleChannels3QueryByPattern() + * @see ITTestFixture + */ + @Test + void handleScrollDataByTestFixture() { + // what + // check scroll + + // -------------------------------------------------------------------------------- + // set up test fixture + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // note + // option + // ~name + // ~tag + // ~size + // ~from + // other + // see ChannelFinderChannelsIT#handleChannels3QueryByPattern() + // channels (all) + // channel (name) + // property name (domain) + // property name (element) + // property name (type) + // property name (cell) + // tag (name) + // combinations + // -------------------------------------------------------------------------------- + + ITTestFixture.setup(); + + try { + Scroll actual = null; + + // channels (all) + + actual = + ITUtilScroll.assertQueryChannels("", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId(), 0); + + // channel (name) + + actual = ITUtilScroll.assertQueryChannels("?~name=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?~name=ABC:DEF-GHI:JKL:001", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~name=ABC:DEF-GHI:JKL:001", 0); + + actual = ITUtilScroll.assertQueryChannels("?~name=*001", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=*001", 0); + + actual = ITUtilScroll.assertQueryChannels("?~name=*ABC:DEF-XYZ:JKL:01?", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~name=*ABC:DEF-XYZ:JKL:01?", 0); + + actual = ITUtilScroll.assertQueryChannels("?~name=ABC:DEF-???:JKL:003", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~name=ABC:DEF-???:JKL:003", 0); + + actual = ITUtilScroll.assertQueryChannels("?~size=0", 0); + + actual = ITUtilScroll.assertQueryChannels("?~size=5", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=5", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=5", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?~size=100", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=100", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?~size=3&~from=-1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); + + actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=0", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 0); + + actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=1", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~size=3&~from=1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); + + actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=2", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~size=3&~from=2", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); + + actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=3", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~size=3&~from=3", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); + + actual = ITUtilScroll.assertQueryChannels("?~name=*1*&~size=4&~from=2", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~name=*1*&~size=4&~from=2", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + // property name (domain) + + actual = ITUtilScroll.assertQueryChannels("?domain=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=cryo", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cryo", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=power", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=power", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=cry?", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cry?", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=?????r?????", 0); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=?????r?????", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=?r??", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=?r??", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=?r???", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=*a*", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=?ow*&~size=4&~from=2", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=?ow*&~size=4&~from=2", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = + ITUtilScroll.assertQueryChannels( + "?domain=cryo&domain=power", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=cryo&domain=power", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?", 5); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*o&domain=asdf?", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?&~size=3", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?&~size=3&~from=1", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3&~from=1", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = ITUtilScroll.assertQueryChannels("?domain!=cryo", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain!=*r", 5); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=*r", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain!=cryo&~size=4", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain!=cryo&~size=4", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain!=cryo&~size=4", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain!=cryo&~size=4&~from=0", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain!=cryo&~size=4&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain!=cryo&~size=4&~from=0", 0); + + // property name (element) + + actual = ITUtilScroll.assertQueryChannels("?element=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=source", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=source", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=initial", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=radio", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=radio", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=magnet", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=magnet", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=supra", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=supra", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=*i?", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=*i?", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=?i*", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=*a*&~size=2&~from=4", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=*a*&~size=2&~from=4", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = ITUtilScroll.assertQueryChannels("?element=initial&element=radio&element=supra", 6); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=initial&element=radio&element=supra", 0); + + actual = ITUtilScroll.assertQueryChannels("?element=rad?o&element=asdf?", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=rad?o&element=asdf?", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?element=initial&element=radio&element=supra&~size=4", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?element=initial&element=radio&element=supra&~size=4&~from=3", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4&~from=3", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = ITUtilScroll.assertQueryChannels("?element!=initial", 8); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=initial", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?element!=source&element!=initial", + ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element!=source&element!=initial", 0); + + actual = ITUtilScroll.assertQueryChannels("?element!=source&element!=initial&~size=6", 6); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element!=source&element!=initial&~size=6", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element!=source&element!=initial&~size=6", 0); + + actual = + ITUtilScroll.assertQueryChannels("?element!=source&element!=initial&~size=6&~from=5", 5); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?element!=source&element!=initial&~size=6&~from=5", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + // property name (type) + + actual = ITUtilScroll.assertQueryChannels("?type=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=read", 4); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=read", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=write", 4); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=write", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=readwrite", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=readwrite", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=read*", 6); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=read*", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=*write", 6); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=*write", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?type=*r*", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=*r*", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=??a?&~size=2&~from=4", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite", 6); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?type=write&type=readwrite", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=writ?&type=writ*", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?type=writ?&type=writ*", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite&~size=10", 6); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?type=write&type=readwrite&~size=10", 0); + + actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite&~size=10&~from=7", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?type!=asdf", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type!=asdf", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?type!=asdf&~size=100", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?type!=asdf&~size=100&~from=0", 0); + + // property name (cell) + + actual = ITUtilScroll.assertQueryChannels("?cell=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block1", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block2", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block2", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block3", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block3", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block4", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block4", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block5", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block5", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?cell=block?", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block?", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=*2", 2); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=*2", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block?&~size=5&~from=5", 5); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block?&~size=5&~from=5", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = ITUtilScroll.assertQueryChannels("?cell=block1&cell=block2", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=*1&cell=*2", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=*1&cell=*2", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell=block1&cell=block2&cell=block2&~size=1", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?cell!=block", ITTestFixture.channels_all_properties_tags.length); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell!=block", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell!=block?", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell!=block*&size=10", 0); + + actual = ITUtilScroll.assertQueryChannels("?cell!=block?*&size=10&~from=0", 0); + + // tag (name) + + actual = ITUtilScroll.assertQueryChannels("?~tag=asdf", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=archived", 4); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=archived", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=handle_this", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=handle_this", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?~tag=noteworthy", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=noteworthy", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=not_used", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=*_*", 3); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=*_*", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=*i*", 6); + actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=*i*", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag=*i*&~size=4&~from=1", 4); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~tag=*i*&~size=4&~from=1", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + + actual = ITUtilScroll.assertQueryChannels("?~tag!=noteworthy", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?~tag!=not_used", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag!=not_used", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags.length); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?~tag!=not_used&~size=10", 0); + + actual = ITUtilScroll.assertQueryChannels("?~tag!=not_used&~size=10&~from=10", 0); + + // combinations + + actual = ITUtilScroll.assertQueryChannels("?domain=cryo&element=source&cell=block1", 1); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=cryo&element=source&cell=block1", 0); + + actual = ITUtilScroll.assertQueryChannels("?domain=power&type=write&~tag=noteworthy", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=power&type=write&~tag=noteworthy", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?domain=power&type=write&type=????write&~tag=noteworthy", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=power&type=write&type=????write&~tag=noteworthy", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 2); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 0); + + actual = + ITUtilScroll.assertQueryChannels( + "?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", 3); + actual = + ITUtilScroll.assertContinueChannelsQuery( + "/" + actual.getId() + "?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", + HttpURLConnection.HTTP_INTERNAL_ERROR, + -1); + } catch (Exception e) { + fail(); } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#SCROLL_RESOURCE_URI}. - * - * @see ChannelFinderChannelsIT#handleChannels3QueryByPattern() - * @see ITTestFixture - */ - @Test - void handleScrollDataByTestFixture() { - // what - // check scroll - - // -------------------------------------------------------------------------------- - // set up test fixture - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // note - // option - // ~name - // ~tag - // ~size - // ~from - // other - // see ChannelFinderChannelsIT#handleChannels3QueryByPattern() - // channels (all) - // channel (name) - // property name (domain) - // property name (element) - // property name (type) - // property name (cell) - // tag (name) - // combinations - // -------------------------------------------------------------------------------- - - ITTestFixture.setup(); - - try { - Scroll actual = null; - - // channels (all) - - actual = ITUtilScroll.assertQueryChannels("", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId(), 0); - - // channel (name) - - actual = ITUtilScroll.assertQueryChannels("?~name=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?~name=ABC:DEF-GHI:JKL:001", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=ABC:DEF-GHI:JKL:001", 0); - - actual = ITUtilScroll.assertQueryChannels("?~name=*001", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=*001", 0); - - actual = ITUtilScroll.assertQueryChannels("?~name=*ABC:DEF-XYZ:JKL:01?", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=*ABC:DEF-XYZ:JKL:01?", 0); - - actual = ITUtilScroll.assertQueryChannels("?~name=ABC:DEF-???:JKL:003", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=ABC:DEF-???:JKL:003", 0); - - actual = ITUtilScroll.assertQueryChannels("?~size=0", 0); - - actual = ITUtilScroll.assertQueryChannels("?~size=5", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=5", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=5", 0); - - actual = ITUtilScroll.assertQueryChannels("?~size=100", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=100", 0); - - actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=-1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=0", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=0", 0); - - actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=1", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=2", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=2", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?~size=3&~from=3", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~size=3&~from=3", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?~name=*1*&~size=4&~from=2", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~name=*1*&~size=4&~from=2", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - // property name (domain) - - actual = ITUtilScroll.assertQueryChannels("?domain=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=cryo", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cryo", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=power", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=power", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=cry?", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cry?", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=?????r?????", 0); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=?????r?????", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=?r??", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=?r??", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=?r???", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*a*", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=?ow*&~size=4&~from=2", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=?ow*&~size=4&~from=2", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?domain=cryo&domain=power", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cryo&domain=power", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*o&domain=asdf?", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?&~size=3", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*o&domain=asdf?&~size=3&~from=1", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*o&domain=asdf?&~size=3&~from=1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?domain!=cryo", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain!=*r", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=*r", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain!=cryo&~size=4", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo&~size=4", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo&~size=4", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain!=cryo&~size=4&~from=0", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo&~size=4&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain!=cryo&~size=4&~from=0", 0); - - // property name (element) - - actual = ITUtilScroll.assertQueryChannels("?element=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=source", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=source", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=initial", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=radio", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=radio", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=magnet", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=magnet", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=supra", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=supra", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=*i?", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=*i?", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=?i*", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=*a*&~size=2&~from=4", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=*a*&~size=2&~from=4", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?element=initial&element=radio&element=supra", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial&element=radio&element=supra", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=rad?o&element=asdf?", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=rad?o&element=asdf?", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=initial&element=radio&element=supra&~size=4", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4", 0); - - actual = ITUtilScroll.assertQueryChannels("?element=initial&element=radio&element=supra&~size=4&~from=3", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element=initial&element=radio&element=supra&~size=4&~from=3", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?element!=initial", 8); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=initial", 0); - - actual = ITUtilScroll.assertQueryChannels("?element!=source&element!=initial", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=source&element!=initial", 0); - - actual = ITUtilScroll.assertQueryChannels("?element!=source&element!=initial&~size=6", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=source&element!=initial&~size=6", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=source&element!=initial&~size=6", 0); - - actual = ITUtilScroll.assertQueryChannels("?element!=source&element!=initial&~size=6&~from=5", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?element!=source&element!=initial&~size=6&~from=5", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - // property name (type) - - actual = ITUtilScroll.assertQueryChannels("?type=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=read", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=read", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=write", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=write", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=readwrite", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=readwrite", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=read*", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=read*", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=*write", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=*write", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=*r*", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=*r*", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=??a?&~size=2&~from=4", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=write&type=readwrite", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=writ?&type=writ*", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=writ?&type=writ*", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite&~size=10", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type=write&type=readwrite&~size=10", 0); - - actual = ITUtilScroll.assertQueryChannels("?type=write&type=readwrite&~size=10&~from=7", 0); - - actual = ITUtilScroll.assertQueryChannels("?type!=asdf", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type!=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?type!=asdf&~size=100", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type!=asdf&~size=100", 0); - - actual = ITUtilScroll.assertQueryChannels("?type!=asdf&~size=100&~from=0", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?type!=asdf&~size=100&~from=0", 0); - - // property name (cell) - - actual = ITUtilScroll.assertQueryChannels("?cell=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block1", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block2", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block2", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block3", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block3", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block4", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block4", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block5", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block5", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block?", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block?", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=*2", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=*2", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block?&~size=5&~from=5", 5); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block?&~size=5&~from=5", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?cell=block1&cell=block2", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=*1&cell=*2", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=*1&cell=*2", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block1&cell=block2&cell=block2&~size=1", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell=block1&cell=block2&cell=block2&~size=1&~from=0", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell!=block", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?cell!=block", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell!=block?", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell!=block*&size=10", 0); - - actual = ITUtilScroll.assertQueryChannels("?cell!=block?*&size=10&~from=0", 0); - - // tag (name) - - actual = ITUtilScroll.assertQueryChannels("?~tag=asdf", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=archived", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=archived", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=handle_this", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=handle_this", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=noteworthy", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=noteworthy", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=not_used", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=*_*", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=*_*", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=*i*", 6); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=*i*", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag=*i*&~size=4&~from=1", 4); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag=*i*&~size=4&~from=1", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - - actual = ITUtilScroll.assertQueryChannels("?~tag!=noteworthy", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag!=not_used", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag!=not_used", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag!=not_used&~size=10", ITTestFixture.channels_all_properties_tags.length); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?~tag!=not_used&~size=10", 0); - - actual = ITUtilScroll.assertQueryChannels("?~tag!=not_used&~size=10&~from=10", 0); - - // combinations - - actual = ITUtilScroll.assertQueryChannels("?domain=cryo&element=source&cell=block1", 1); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=cryo&element=source&cell=block1", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=power&type=write&~tag=noteworthy", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=power&type=write&~tag=noteworthy", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=power&type=write&type=????write&~tag=noteworthy", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=power&type=write&type=????write&~tag=noteworthy", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 2); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*r*&type=*write&~tag=archived&~tag=noteworthy", 0); - - actual = ITUtilScroll.assertQueryChannels("?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", 3); - actual = ITUtilScroll.assertContinueChannelsQuery("/" + actual.getId() + "?domain=*r*&type=*write&~tag=noteworthy&~size=3&~from=2", HttpURLConnection.HTTP_INTERNAL_ERROR, -1); - } catch (Exception e) { - fail(); - } - - // -------------------------------------------------------------------------------- - // tear down test fixture - // -------------------------------------------------------------------------------- - - ITTestFixture.tearDown(); - } + // -------------------------------------------------------------------------------- + // tear down test fixture + // -------------------------------------------------------------------------------- + ITTestFixture.tearDown(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderTagsIT.java b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderTagsIT.java index a22e19ed..1ca5c35e 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderTagsIT.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ChannelFinderTagsIT.java @@ -18,8 +18,11 @@ package org.phoebus.channelfinder.docker; -import com.fasterxml.jackson.databind.ObjectMapper; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.net.HttpURLConnection; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -30,17 +33,11 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.net.HttpURLConnection; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - /** - * Integration tests for ChannelFinder and Elasticsearch with focus on usage of - * {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. + * Integration tests for ChannelFinder and Elasticsearch with focus on usage of {@link + * org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.TagManager * @see org.phoebus.channelfinder.docker.ITUtil * @see org.phoebus.channelfinder.docker.ITUtilTags @@ -48,813 +45,882 @@ @Testcontainers class ChannelFinderTagsIT { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // requires - // elastic indices for ChannelFinder, ensured at start-up - // environment - // default ports, can be exposed differently externally to avoid interference with any running instance - // demo_auth enabled - // docker containers shared for tests - // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other tests - // each test uses multiple endpoints in ChannelFinder API - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API - // -------------------- - // Retrieve a Tag .../tags/ GET - // List Tags .../tags GET - // Create/Replace a Tag .../tags/ PUT - // Add Tag to a Single Channel .../tags// PUT - // Create/Replace Tags .../tags/ PUT - // Add Tag to Multiple Channels .../tags/ POST - // Add Multiple Tags .../tags POST - // Delete Tag from Single Channel .../tags// DELETE - // Delete Tag .../tags/ DELETE - // ------------------------------------------------------------------------------------------------ - - // test data - // tags t1 - t10, owner o1 - // tag t1, owner o2 - - static Tag tag_t1_owner_o1; - static Tag tag_t2_owner_o1; - static Tag tag_t3_owner_o1; - static Tag tag_t4_owner_o1; - static Tag tag_t5_owner_o1; - static Tag tag_t6_owner_o1; - static Tag tag_t7_owner_o1; - static Tag tag_t8_owner_o1; - static Tag tag_t9_owner_o1; - static Tag tag_t10_owner_o1; - - static Tag tag_t1_owner_o2; - - @Container - public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); - - @BeforeAll - public static void setupObjects() { - tag_t1_owner_o1 = new Tag("t1", "o1"); - tag_t2_owner_o1 = new Tag("t2", "o1"); - tag_t3_owner_o1 = new Tag("t3", "o1"); - tag_t4_owner_o1 = new Tag("t4", "o1"); - tag_t5_owner_o1 = new Tag("t5", "o1"); - tag_t6_owner_o1 = new Tag("t6", "o1"); - tag_t7_owner_o1 = new Tag("t7", "o1"); - tag_t8_owner_o1 = new Tag("t8", "o1"); - tag_t9_owner_o1 = new Tag("t9", "o1"); - tag_t10_owner_o1 = new Tag("t10", "o1"); - - tag_t1_owner_o2 = new Tag("t1", "o2"); - } - - @AfterAll - public static void tearDownObjects() { - tag_t1_owner_o1 = null; - tag_t2_owner_o1 = null; - tag_t3_owner_o1 = null; - tag_t4_owner_o1 = null; - tag_t5_owner_o1 = null; - tag_t6_owner_o1 = null; - tag_t7_owner_o1 = null; - tag_t8_owner_o1 = null; - tag_t9_owner_o1 = null; - tag_t10_owner_o1 = null; - - tag_t1_owner_o2 = null; - } - - @AfterAll - public static void extractJacocoReport() { - // extract jacoco report from container file system - ITUtil.extractJacocoReport(ENVIRONMENT, - ITUtil.JACOCO_TARGET_PREFIX + ChannelFinderTagsIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); - } - - @Test - void channelfinderUp() { - try { - int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); - - assertEquals(HttpURLConnection.HTTP_OK, responseCode); - } catch (Exception e) { - fail(); - } - } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTagRetrieveCheck() { - // what - // check(s) for retrieve tag - // e.g. - // retrieve non-existing tag - - ITUtilTags.assertRetrieveTag("/t11", HttpURLConnection.HTTP_NOT_FOUND); + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // requires + // elastic indices for ChannelFinder, ensured at start-up + // environment + // default ports, can be exposed differently externally to avoid interference with + // any running instance + // demo_auth enabled + // docker containers shared for tests + // each test to leave ChannelFinder, Elasticsearch in clean state - not disturb other + // tests + // each test uses multiple endpoints in ChannelFinder API + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + // CHANNELFINDER API + // -------------------- + // Retrieve a Tag .../tags/ GET + // List Tags .../tags GET + // Create/Replace a Tag .../tags/ PUT + // Add Tag to a Single Channel .../tags// PUT + // Create/Replace Tags .../tags/ PUT + // Add Tag to Multiple Channels .../tags/ POST + // Add Multiple Tags .../tags POST + // Delete Tag from Single Channel .../tags// DELETE + // Delete Tag .../tags/ DELETE + // + // ------------------------------------------------------------------------------------------------ + + // test data + // tags t1 - t10, owner o1 + // tag t1, owner o2 + + static Tag tag_t1_owner_o1; + static Tag tag_t2_owner_o1; + static Tag tag_t3_owner_o1; + static Tag tag_t4_owner_o1; + static Tag tag_t5_owner_o1; + static Tag tag_t6_owner_o1; + static Tag tag_t7_owner_o1; + static Tag tag_t8_owner_o1; + static Tag tag_t9_owner_o1; + static Tag tag_t10_owner_o1; + + static Tag tag_t1_owner_o2; + + @Container public static final ComposeContainer ENVIRONMENT = ITUtil.defaultComposeContainers(); + + @BeforeAll + public static void setupObjects() { + tag_t1_owner_o1 = new Tag("t1", "o1"); + tag_t2_owner_o1 = new Tag("t2", "o1"); + tag_t3_owner_o1 = new Tag("t3", "o1"); + tag_t4_owner_o1 = new Tag("t4", "o1"); + tag_t5_owner_o1 = new Tag("t5", "o1"); + tag_t6_owner_o1 = new Tag("t6", "o1"); + tag_t7_owner_o1 = new Tag("t7", "o1"); + tag_t8_owner_o1 = new Tag("t8", "o1"); + tag_t9_owner_o1 = new Tag("t9", "o1"); + tag_t10_owner_o1 = new Tag("t10", "o1"); + + tag_t1_owner_o2 = new Tag("t1", "o2"); + } + + @AfterAll + public static void tearDownObjects() { + tag_t1_owner_o1 = null; + tag_t2_owner_o1 = null; + tag_t3_owner_o1 = null; + tag_t4_owner_o1 = null; + tag_t5_owner_o1 = null; + tag_t6_owner_o1 = null; + tag_t7_owner_o1 = null; + tag_t8_owner_o1 = null; + tag_t9_owner_o1 = null; + tag_t10_owner_o1 = null; + + tag_t1_owner_o2 = null; + } + + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + ITUtil.extractJacocoReport( + ENVIRONMENT, + ITUtil.JACOCO_TARGET_PREFIX + + ChannelFinderTagsIT.class.getSimpleName() + + ITUtil.JACOCO_TARGET_SUFFIX); + } + + @Test + void channelfinderUp() { + try { + int responseCode = ITUtil.sendRequestStatusCode(ITUtil.HTTP_IP_PORT_CHANNELFINDER); + + assertEquals(HttpURLConnection.HTTP_OK, responseCode); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTagRemoveCheck() { - // what - // check(s) for remove tag - // e.g. - // remove non-existing tag - - try { - // might be both 401, 404 - // 401 UNAUTHORIZED - // 404 NOT_FOUND - - ITUtilTags.assertRemoveTag(AuthorizationChoice.NONE, "/t11", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertRemoveTag(AuthorizationChoice.USER, "/t11", HttpURLConnection.HTTP_NOT_FOUND); - ITUtilTags.assertRemoveTag(AuthorizationChoice.ADMIN, "/t11", HttpURLConnection.HTTP_NOT_FOUND); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTagRetrieveCheck() { + // what + // check(s) for retrieve tag + // e.g. + // retrieve non-existing tag + + ITUtilTags.assertRetrieveTag("/t11", HttpURLConnection.HTTP_NOT_FOUND); + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTagRemoveCheck() { + // what + // check(s) for remove tag + // e.g. + // remove non-existing tag + + try { + // might be both 401, 404 + // 401 UNAUTHORIZED + // 404 NOT_FOUND + + ITUtilTags.assertRemoveTag( + AuthorizationChoice.NONE, "/t11", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertRemoveTag( + AuthorizationChoice.USER, "/t11", HttpURLConnection.HTTP_NOT_FOUND); + ITUtilTags.assertRemoveTag( + AuthorizationChoice.ADMIN, "/t11", HttpURLConnection.HTTP_NOT_FOUND); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTagCreateUpdateCheckJson() { - // what - // check(s) for create / update tag - // e.g. - // user without required role TagMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_incomplete2 = "{\"incomplete\""; - String json_incomplete3 = "{\"incomplete}"; - String json_incomplete4 = "{\"\"}"; - String json_incomplete5 = "{incomplete\"}"; - String json_incomplete6 = "\"incomplete\"}"; - String json_incomplete7 = "{"; - String json_incomplete8 = "}"; - String json_incomplete9 = "\""; - - String json_tag_t1_name_na = "{\"na\":\"t1\",\"owner\":\"o1\"}"; - String json_tag_t1_owner_ow = "{\"name\":\"t1\",\"ow\":\"o1\"}"; - - String json_tag_t1_channels_c1 = "{\"name\":\"t1\",\"owner\":\"o1\",\"channels\":[{\"name\":\"c1\",\"owner\":\"o1\",\"properties\":[],\"tags\":[{\"name\":\"t1\",\"owner\":\"o1\",\"channels\":[]}]}]}"; - - try { - ITUtilTags.assertListTags(0); - - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_channels_c1, HttpURLConnection.HTTP_NOT_FOUND); - - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_name_na, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_owner_ow, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/t1", json_tag_t1_channels_c1, HttpURLConnection.HTTP_NOT_FOUND); - - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTagCreateUpdateCheckJson() { + // what + // check(s) for create / update tag + // e.g. + // user without required role TagMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_incomplete2 = "{\"incomplete\""; + String json_incomplete3 = "{\"incomplete}"; + String json_incomplete4 = "{\"\"}"; + String json_incomplete5 = "{incomplete\"}"; + String json_incomplete6 = "\"incomplete\"}"; + String json_incomplete7 = "{"; + String json_incomplete8 = "}"; + String json_incomplete9 = "\""; + + String json_tag_t1_name_na = "{\"na\":\"t1\",\"owner\":\"o1\"}"; + String json_tag_t1_owner_ow = "{\"name\":\"t1\",\"ow\":\"o1\"}"; + + String json_tag_t1_channels_c1 = + "{\"name\":\"t1\",\"owner\":\"o1\",\"channels\":[{\"name\":\"c1\",\"owner\":\"o1\",\"properties\":[],\"tags\":[{\"name\":\"t1\",\"owner\":\"o1\",\"channels\":[]}]}]}"; + + try { + ITUtilTags.assertListTags(0); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_channels_c1, + HttpURLConnection.HTTP_NOT_FOUND); + + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete1, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete2, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete3, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete4, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete5, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete6, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete7, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete8, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/t1", json_incomplete9, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_name_na, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_owner_ow, + HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, + "/t1", + json_tag_t1_channels_c1, + HttpURLConnection.HTTP_NOT_FOUND); + + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTagCreateUpdateCheck() { - // what - // check(s) for create / update tag - // e.g. - // user without required role TagMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - Tag tag_check = new Tag(); - - try { - ITUtilTags.assertListTags(0); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.NONE, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.NONE, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.USER, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.USER, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - - tag_check.setName(null); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - - tag_check.setName(""); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - - tag_check.setName("asdf"); - tag_check.setOwner(null); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - - tag_check.setName("asdf"); - tag_check.setOwner(""); - - ITUtilTags.assertCreateReplaceTag (AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - ITUtilTags.assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTagCreateUpdateCheck() { + // what + // check(s) for create / update tag + // e.g. + // user without required role TagMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + Tag tag_check = new Tag(); + + try { + ITUtilTags.assertListTags(0); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.NONE, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.NONE, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.USER, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.USER, "/t1", tag_t1_owner_o1, HttpURLConnection.HTTP_UNAUTHORIZED); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + + tag_check.setName(null); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + + tag_check.setName(""); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + + tag_check.setName("asdf"); + tag_check.setOwner(null); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + + tag_check.setName("asdf"); + tag_check.setOwner(""); + + ITUtilTags.assertCreateReplaceTag( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + ITUtilTags.assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, "/asdf", tag_check, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTag() { - // what - // user with required role TagMod - // create tag - // list, create tag, list, retrieve, delete (unauthorized), delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTag() { + // what + // user with required role TagMod + // create tag + // list, create tag, list, retrieve, delete (unauthorized), delete, list - try { - ITUtilTags.assertListTags(0); + try { + ITUtilTags.assertListTags(0); - ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag(AuthorizationChoice.ADMIN, "/t1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1?withChannels=true", tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1?withChannels=false", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1?withChannels=true", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1?withChannels=false", tag_t1_owner_o1); - ITUtilTags.assertRemoveTag(AuthorizationChoice.NONE, "/t1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertRemoveTag(AuthorizationChoice.USER, "/t1", HttpURLConnection.HTTP_UNAUTHORIZED); - ITUtilTags.assertRemoveTag(AuthorizationChoice.ADMIN, "/t1", HttpURLConnection.HTTP_OK); + ITUtilTags.assertRemoveTag( + AuthorizationChoice.NONE, "/t1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertRemoveTag( + AuthorizationChoice.USER, "/t1", HttpURLConnection.HTTP_UNAUTHORIZED); + ITUtilTags.assertRemoveTag(AuthorizationChoice.ADMIN, "/t1", HttpURLConnection.HTTP_OK); - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTag2() { - // what - // create tags, one by one - // list, create tag * 2, list, retrieve, retrieve, delete, list, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTag2() { + // what + // create tags, one by one + // list, create tag * 2, list, retrieve, retrieve, delete, list, retrieve, delete, list - try { - ITUtilTags.assertListTags(0); + try { + ITUtilTags.assertListTags(0); - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertCreateReplaceTag("/t2", tag_t2_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t2", tag_t2_owner_o1); - ITUtilTags.assertListTags(2, - tag_t1_owner_o1, - tag_t2_owner_o1); + ITUtilTags.assertListTags(2, tag_t1_owner_o1, tag_t2_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); - ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertListTags(1, tag_t2_owner_o1); + ITUtilTags.assertListTags(1, tag_t2_owner_o1); - ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); + ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); - ITUtilTags.assertRemoveTag("/t2"); + ITUtilTags.assertRemoveTag("/t2"); - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTag3RenameOwner() { - // what - // replace tag, rename owner - // list, create tag, list, retrieve, update, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTag3RenameOwner() { + // what + // replace tag, rename owner + // list, create tag, list, retrieve, update, retrieve, delete, list - try { - ITUtilTags.assertListTags(0); + try { + ITUtilTags.assertListTags(0); - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_owner_o2); + ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_owner_o2); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o2); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o2); - ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTag4ReplaceNonExisting() { - // what - // replace non-existing tag - // list, update, list, retrieve, delete, list + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTag4ReplaceNonExisting() { + // what + // replace non-existing tag + // list, update, list, retrieve, delete, list - try { - ITUtilTags.assertListTags(0); + try { + ITUtilTags.assertListTags(0); - ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_owner_o1); + ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleTag5SingleChannel() { - // what - // add tag to single channel - // clean start, create tag, create channel, - // add tag to single channel, - // list, retrieve - // remove tag from single channel, - // delete channel, delete tag, clean end + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleTag5SingleChannel() { + // what + // add tag to single channel + // clean start, create tag, create channel, + // add tag to single channel, + // list, retrieve + // remove tag from single channel, + // delete channel, delete tag, clean end - Channel channel_c1 = new Channel("c1", "o1"); + Channel channel_c1 = new Channel("c1", "o1"); - Tag tag_t1 = new Tag("t1", "o1"); + Tag tag_t1 = new Tag("t1", "o1"); - Channel channel_c1_tags = new Channel("c1", "o1"); - channel_c1_tags.addTag(tag_t1); + Channel channel_c1_tags = new Channel("c1", "o1"); + channel_c1_tags.addTag(tag_t1); - Tag tag_t1_channels = new Tag("t1", "o1"); - tag_t1_channels.getChannels().add(channel_c1_tags); + Tag tag_t1_channels = new Tag("t1", "o1"); + tag_t1_channels.getChannels().add(channel_c1_tags); - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- - ITUtilProperties.assertListProperties(0); + ITUtilProperties.assertListProperties(0); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); - ITUtilChannels.assertListChannels(1, - channel_c1); + ITUtilChannels.assertListChannels(1, channel_c1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - // -------------------------------------------------------------------------------- - // complex tests, add tag to single channel - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // complex tests, add tag to single channel + // -------------------------------------------------------------------------------- - ITUtilTags.assertAddTagSingleChannel("/t1/c1", tag_t1_owner_o1); + ITUtilTags.assertAddTagSingleChannel("/t1/c1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_channels); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_channels); - ITUtilChannels.assertListChannels(1, channel_c1_tags); + ITUtilChannels.assertListChannels(1, channel_c1_tags); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_tags); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_tags); - // -------------------------------------------------------------------------------- - // complex tests, remove tag from single channel - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // complex tests, remove tag from single channel + // -------------------------------------------------------------------------------- - ITUtilTags.assertRemoveTagSingleChannel("/t1/c1"); + ITUtilTags.assertRemoveTagSingleChannel("/t1/c1"); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilChannels.assertListChannels(1, channel_c1); + ITUtilChannels.assertListChannels(1, channel_c1); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } + } - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. - */ - @Test - void handleTag6MultipleChannels() { - // what - // add tag to multiple channels - // clean start, create tag, create channel(s), - // add tag to multiple channel(s), - // list, retrieve - // delete tag, delete channel(s), clean end + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#PROPERTY_RESOURCE_URI}. */ + @Test + void handleTag6MultipleChannels() { + // what + // add tag to multiple channels + // clean start, create tag, create channel(s), + // add tag to multiple channel(s), + // list, retrieve + // delete tag, delete channel(s), clean end - Channel channel_c1 = new Channel("c1", "o1"); - Channel channel_c2 = new Channel("c2", "o1"); - Channel channel_c3 = new Channel("c3", "o1"); + Channel channel_c1 = new Channel("c1", "o1"); + Channel channel_c2 = new Channel("c2", "o1"); + Channel channel_c3 = new Channel("c3", "o1"); - Tag tag_t1 = new Tag("t1", "o1"); + Tag tag_t1 = new Tag("t1", "o1"); - Channel channel_c1_tags = new Channel("c1", "o1"); - Channel channel_c2_tags = new Channel("c2", "o1"); - Channel channel_c3_tags = new Channel("c3", "o1"); - channel_c1_tags.addTag(tag_t1); - channel_c2_tags.addTag(tag_t1); - channel_c3_tags.addTag(tag_t1); + Channel channel_c1_tags = new Channel("c1", "o1"); + Channel channel_c2_tags = new Channel("c2", "o1"); + Channel channel_c3_tags = new Channel("c3", "o1"); + channel_c1_tags.addTag(tag_t1); + channel_c2_tags.addTag(tag_t1); + channel_c3_tags.addTag(tag_t1); - Tag tag_t1_channels = new Tag("t1", "o1"); - tag_t1_channels.getChannels().add(channel_c1); - tag_t1_channels.getChannels().add(channel_c2); - tag_t1_channels.getChannels().add(channel_c3); + Tag tag_t1_channels = new Tag("t1", "o1"); + tag_t1_channels.getChannels().add(channel_c1); + tag_t1_channels.getChannels().add(channel_c2); + tag_t1_channels.getChannels().add(channel_c3); - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- - ITUtilProperties.assertListProperties(0); + ITUtilProperties.assertListProperties(0); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_owner_o1); - ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); - ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2); - ITUtilChannels.assertCreateReplaceChannel("/c3", channel_c3); + ITUtilChannels.assertCreateReplaceChannel("/c1", channel_c1); + ITUtilChannels.assertCreateReplaceChannel("/c2", channel_c2); + ITUtilChannels.assertCreateReplaceChannel("/c3", channel_c3); - ITUtilChannels.assertListChannels(3, - channel_c1, - channel_c2, - channel_c3); + ITUtilChannels.assertListChannels(3, channel_c1, channel_c2, channel_c3); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3); - // -------------------------------------------------------------------------------- - // complex tests, add tag to multiple channels - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // complex tests, add tag to multiple channels + // -------------------------------------------------------------------------------- - ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_channels); + ITUtilTags.assertAddTagMultipleChannels("/t1", tag_t1_channels); - ITUtilTags.assertListTags(1, tag_t1_owner_o1); + ITUtilTags.assertListTags(1, tag_t1_owner_o1); - ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_channels); + ITUtilTags.assertCreateReplaceTag("/t1", tag_t1_channels); - ITUtilChannels.assertListChannels(3, - channel_c1_tags, - channel_c2_tags, - channel_c3_tags); + ITUtilChannels.assertListChannels(3, channel_c1_tags, channel_c2_tags, channel_c3_tags); - ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_tags); - ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_tags); - ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_tags); + ITUtilChannels.assertRetrieveChannel("/c1", channel_c1_tags); + ITUtilChannels.assertRetrieveChannel("/c2", channel_c2_tags); + ITUtilChannels.assertRetrieveChannel("/c3", channel_c3_tags); - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- - ITUtilChannels.assertDeleteChannel("/c3"); - ITUtilChannels.assertDeleteChannel("/c2"); - ITUtilChannels.assertDeleteChannel("/c1"); + ITUtilChannels.assertDeleteChannel("/c3"); + ITUtilChannels.assertDeleteChannel("/c2"); + ITUtilChannels.assertDeleteChannel("/c1"); - ITUtilChannels.assertListChannels(0); + ITUtilChannels.assertListChannels(0); - ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertListTags(0); + ITUtilTags.assertListTags(0); - ITUtilProperties.assertListProperties(0); - } catch (Exception e) { - fail(); - } + ITUtilProperties.assertListProperties(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTagsCreateUpdateCheck() { - // what - // check(s) for create tags - // e.g. - // user without required role TagMod - // content - // json - incomplete - // name - null, empty - // owner - null, empty - // channel - exists - - String json_incomplete1 = "{\"incomplete\"}"; - String json_tag_t1_name_na = "{\"na\":\"t1\",\"owner\":\"o1\"}"; - String json_tag_t1_owner_ow = "{\"name\":\"t1\",\"ow\":\"o1\"}"; - - ObjectMapper mapper = new ObjectMapper(); - - try { - ITUtilTags.assertListTags(0); - - String json_multiple = "[" - + mapper.writeValueAsString(tag_t1_owner_o1) - + "," + mapper.writeValueAsString(tag_t2_owner_o1) - + "," + mapper.writeValueAsString(tag_t3_owner_o1) - + "," + mapper.writeValueAsString(tag_t4_owner_o1) - + "," + mapper.writeValueAsString(tag_t5_owner_o1) - + "," + mapper.writeValueAsString(tag_t6_owner_o1) - + "," + mapper.writeValueAsString(tag_t7_owner_o1) - + "," + mapper.writeValueAsString(tag_t8_owner_o1) - + "," + mapper.writeValueAsString(tag_t9_owner_o1) - + "," + mapper.writeValueAsString(tag_t10_owner_o1) - + "," + json_incomplete1 + "]"; - - ITUtilTags.assertCreateReplaceTags(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - json_multiple = "[" - + mapper.writeValueAsString(tag_t1_owner_o1) - + "," + mapper.writeValueAsString(tag_t2_owner_o1) - + "," + mapper.writeValueAsString(tag_t3_owner_o1) - + "," + mapper.writeValueAsString(tag_t4_owner_o1) - + "," + mapper.writeValueAsString(tag_t5_owner_o1) - + "," + mapper.writeValueAsString(tag_t6_owner_o1) - + "," + mapper.writeValueAsString(tag_t7_owner_o1) - + "," + mapper.writeValueAsString(tag_t8_owner_o1) - + "," + mapper.writeValueAsString(tag_t9_owner_o1) - + "," + mapper.writeValueAsString(tag_t10_owner_o1) - + "," + json_tag_t1_name_na + "]"; - - ITUtilTags.assertCreateReplaceTags(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); - - json_multiple = "[" - + mapper.writeValueAsString(tag_t1_owner_o1) - + "," + mapper.writeValueAsString(tag_t2_owner_o1) - + "," + mapper.writeValueAsString(tag_t3_owner_o1) - + "," + mapper.writeValueAsString(tag_t4_owner_o1) - + "," + mapper.writeValueAsString(tag_t5_owner_o1) - + "," + mapper.writeValueAsString(tag_t6_owner_o1) - + "," + mapper.writeValueAsString(tag_t7_owner_o1) - + "," + mapper.writeValueAsString(tag_t8_owner_o1) - + "," + mapper.writeValueAsString(tag_t9_owner_o1) - + "," + mapper.writeValueAsString(tag_t10_owner_o1) - + "," + json_tag_t1_owner_ow + "]"; - - ITUtilTags.assertCreateReplaceTags(AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); - - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTagsCreateUpdateCheck() { + // what + // check(s) for create tags + // e.g. + // user without required role TagMod + // content + // json - incomplete + // name - null, empty + // owner - null, empty + // channel - exists + + String json_incomplete1 = "{\"incomplete\"}"; + String json_tag_t1_name_na = "{\"na\":\"t1\",\"owner\":\"o1\"}"; + String json_tag_t1_owner_ow = "{\"name\":\"t1\",\"ow\":\"o1\"}"; + + ObjectMapper mapper = new ObjectMapper(); + + try { + ITUtilTags.assertListTags(0); + + String json_multiple = + "[" + + mapper.writeValueAsString(tag_t1_owner_o1) + + "," + + mapper.writeValueAsString(tag_t2_owner_o1) + + "," + + mapper.writeValueAsString(tag_t3_owner_o1) + + "," + + mapper.writeValueAsString(tag_t4_owner_o1) + + "," + + mapper.writeValueAsString(tag_t5_owner_o1) + + "," + + mapper.writeValueAsString(tag_t6_owner_o1) + + "," + + mapper.writeValueAsString(tag_t7_owner_o1) + + "," + + mapper.writeValueAsString(tag_t8_owner_o1) + + "," + + mapper.writeValueAsString(tag_t9_owner_o1) + + "," + + mapper.writeValueAsString(tag_t10_owner_o1) + + "," + + json_incomplete1 + + "]"; + + ITUtilTags.assertCreateReplaceTags( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + json_multiple = + "[" + + mapper.writeValueAsString(tag_t1_owner_o1) + + "," + + mapper.writeValueAsString(tag_t2_owner_o1) + + "," + + mapper.writeValueAsString(tag_t3_owner_o1) + + "," + + mapper.writeValueAsString(tag_t4_owner_o1) + + "," + + mapper.writeValueAsString(tag_t5_owner_o1) + + "," + + mapper.writeValueAsString(tag_t6_owner_o1) + + "," + + mapper.writeValueAsString(tag_t7_owner_o1) + + "," + + mapper.writeValueAsString(tag_t8_owner_o1) + + "," + + mapper.writeValueAsString(tag_t9_owner_o1) + + "," + + mapper.writeValueAsString(tag_t10_owner_o1) + + "," + + json_tag_t1_name_na + + "]"; + + ITUtilTags.assertCreateReplaceTags( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_INTERNAL_ERROR); + + json_multiple = + "[" + + mapper.writeValueAsString(tag_t1_owner_o1) + + "," + + mapper.writeValueAsString(tag_t2_owner_o1) + + "," + + mapper.writeValueAsString(tag_t3_owner_o1) + + "," + + mapper.writeValueAsString(tag_t4_owner_o1) + + "," + + mapper.writeValueAsString(tag_t5_owner_o1) + + "," + + mapper.writeValueAsString(tag_t6_owner_o1) + + "," + + mapper.writeValueAsString(tag_t7_owner_o1) + + "," + + mapper.writeValueAsString(tag_t8_owner_o1) + + "," + + mapper.writeValueAsString(tag_t9_owner_o1) + + "," + + mapper.writeValueAsString(tag_t10_owner_o1) + + "," + + json_tag_t1_owner_ow + + "]"; + + ITUtilTags.assertCreateReplaceTags( + AuthorizationChoice.ADMIN, "", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilTags.assertAddMultipleTags("", json_multiple, HttpURLConnection.HTTP_BAD_REQUEST); + + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTags() { - // what - // create tags - // list, create tags (10), list, retrieve (10), delete (5), list, delete (5), list - - Tag[] tags_10 = new Tag[] { - tag_t1_owner_o1, - tag_t2_owner_o1, - tag_t3_owner_o1, - tag_t4_owner_o1, - tag_t5_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1, - tag_t10_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTags() { + // what + // create tags + // list, create tags (10), list, retrieve (10), delete (5), list, delete (5), list + + Tag[] tags_10 = + new Tag[] { + tag_t1_owner_o1, + tag_t2_owner_o1, + tag_t3_owner_o1, + tag_t4_owner_o1, + tag_t5_owner_o1, + tag_t6_owner_o1, + tag_t7_owner_o1, + tag_t8_owner_o1, + tag_t9_owner_o1, + tag_t10_owner_o1 }; - try { - ITUtilTags.assertListTags(0); - - ITUtilTags.assertCreateReplaceTags("", tags_10); - - ITUtilTags.assertListTags(10, - tag_t1_owner_o1, - tag_t10_owner_o1, - tag_t2_owner_o1, - tag_t3_owner_o1, - tag_t4_owner_o1, - tag_t5_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1); - - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); - ITUtilTags.assertRetrieveTag("/t3", tag_t3_owner_o1); - ITUtilTags.assertRetrieveTag("/t4", tag_t4_owner_o1); - ITUtilTags.assertRetrieveTag("/t5", tag_t5_owner_o1); - ITUtilTags.assertRetrieveTag("/t6", tag_t6_owner_o1); - ITUtilTags.assertRetrieveTag("/t7", tag_t7_owner_o1); - ITUtilTags.assertRetrieveTag("/t8", tag_t8_owner_o1); - ITUtilTags.assertRetrieveTag("/t9", tag_t9_owner_o1); - ITUtilTags.assertRetrieveTag("/t10", tag_t10_owner_o1); - - ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertRemoveTag("/t2"); - ITUtilTags.assertRemoveTag("/t3"); - ITUtilTags.assertRemoveTag("/t4"); - ITUtilTags.assertRemoveTag("/t5"); - - ITUtilTags.assertListTags(5, - tag_t10_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1); - - ITUtilTags.assertRemoveTag("/t6"); - ITUtilTags.assertRemoveTag("/t7"); - ITUtilTags.assertRemoveTag("/t8"); - ITUtilTags.assertRemoveTag("/t9"); - ITUtilTags.assertRemoveTag("/t10"); - - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilTags.assertListTags(0); + + ITUtilTags.assertCreateReplaceTags("", tags_10); + + ITUtilTags.assertListTags( + 10, + tag_t1_owner_o1, + tag_t10_owner_o1, + tag_t2_owner_o1, + tag_t3_owner_o1, + tag_t4_owner_o1, + tag_t5_owner_o1, + tag_t6_owner_o1, + tag_t7_owner_o1, + tag_t8_owner_o1, + tag_t9_owner_o1); + + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); + ITUtilTags.assertRetrieveTag("/t3", tag_t3_owner_o1); + ITUtilTags.assertRetrieveTag("/t4", tag_t4_owner_o1); + ITUtilTags.assertRetrieveTag("/t5", tag_t5_owner_o1); + ITUtilTags.assertRetrieveTag("/t6", tag_t6_owner_o1); + ITUtilTags.assertRetrieveTag("/t7", tag_t7_owner_o1); + ITUtilTags.assertRetrieveTag("/t8", tag_t8_owner_o1); + ITUtilTags.assertRetrieveTag("/t9", tag_t9_owner_o1); + ITUtilTags.assertRetrieveTag("/t10", tag_t10_owner_o1); + + ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t2"); + ITUtilTags.assertRemoveTag("/t3"); + ITUtilTags.assertRemoveTag("/t4"); + ITUtilTags.assertRemoveTag("/t5"); + + ITUtilTags.assertListTags( + 5, tag_t10_owner_o1, tag_t6_owner_o1, tag_t7_owner_o1, tag_t8_owner_o1, tag_t9_owner_o1); + + ITUtilTags.assertRemoveTag("/t6"); + ITUtilTags.assertRemoveTag("/t7"); + ITUtilTags.assertRemoveTag("/t8"); + ITUtilTags.assertRemoveTag("/t9"); + ITUtilTags.assertRemoveTag("/t10"); + + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } - - /** - * Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. - */ - @Test - void handleTags2ReplaceNonExisting() { - // what - // replace non-existing tags - // list, update tags (10), list, retrieve (10), delete (5), list, delete (5), list - - Tag[] tags_10 = new Tag[] { - tag_t1_owner_o1, - tag_t2_owner_o1, - tag_t3_owner_o1, - tag_t4_owner_o1, - tag_t5_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1, - tag_t10_owner_o1 + } + + /** Test {@link org.phoebus.channelfinder.CFResourceDescriptors#TAG_RESOURCE_URI}. */ + @Test + void handleTags2ReplaceNonExisting() { + // what + // replace non-existing tags + // list, update tags (10), list, retrieve (10), delete (5), list, delete (5), list + + Tag[] tags_10 = + new Tag[] { + tag_t1_owner_o1, + tag_t2_owner_o1, + tag_t3_owner_o1, + tag_t4_owner_o1, + tag_t5_owner_o1, + tag_t6_owner_o1, + tag_t7_owner_o1, + tag_t8_owner_o1, + tag_t9_owner_o1, + tag_t10_owner_o1 }; - try { - ITUtilTags.assertListTags(0); - - ITUtilTags.assertAddMultipleTags("", tags_10); - - ITUtilTags.assertListTags(10, - tag_t1_owner_o1, - tag_t10_owner_o1, - tag_t2_owner_o1, - tag_t3_owner_o1, - tag_t4_owner_o1, - tag_t5_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1); - - ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); - ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); - ITUtilTags.assertRetrieveTag("/t3", tag_t3_owner_o1); - ITUtilTags.assertRetrieveTag("/t4", tag_t4_owner_o1); - ITUtilTags.assertRetrieveTag("/t5", tag_t5_owner_o1); - ITUtilTags.assertRetrieveTag("/t6", tag_t6_owner_o1); - ITUtilTags.assertRetrieveTag("/t7", tag_t7_owner_o1); - ITUtilTags.assertRetrieveTag("/t8", tag_t8_owner_o1); - ITUtilTags.assertRetrieveTag("/t9", tag_t9_owner_o1); - ITUtilTags.assertRetrieveTag("/t10", tag_t10_owner_o1); - - ITUtilTags.assertRemoveTag("/t1"); - ITUtilTags.assertRemoveTag("/t2"); - ITUtilTags.assertRemoveTag("/t3"); - ITUtilTags.assertRemoveTag("/t4"); - ITUtilTags.assertRemoveTag("/t5"); - - ITUtilTags.assertListTags(5, - tag_t10_owner_o1, - tag_t6_owner_o1, - tag_t7_owner_o1, - tag_t8_owner_o1, - tag_t9_owner_o1); - - ITUtilTags.assertRemoveTag("/t6"); - ITUtilTags.assertRemoveTag("/t7"); - ITUtilTags.assertRemoveTag("/t8"); - ITUtilTags.assertRemoveTag("/t9"); - ITUtilTags.assertRemoveTag("/t10"); - - ITUtilTags.assertListTags(0); - } catch (Exception e) { - fail(); - } + try { + ITUtilTags.assertListTags(0); + + ITUtilTags.assertAddMultipleTags("", tags_10); + + ITUtilTags.assertListTags( + 10, + tag_t1_owner_o1, + tag_t10_owner_o1, + tag_t2_owner_o1, + tag_t3_owner_o1, + tag_t4_owner_o1, + tag_t5_owner_o1, + tag_t6_owner_o1, + tag_t7_owner_o1, + tag_t8_owner_o1, + tag_t9_owner_o1); + + ITUtilTags.assertRetrieveTag("/t1", tag_t1_owner_o1); + ITUtilTags.assertRetrieveTag("/t2", tag_t2_owner_o1); + ITUtilTags.assertRetrieveTag("/t3", tag_t3_owner_o1); + ITUtilTags.assertRetrieveTag("/t4", tag_t4_owner_o1); + ITUtilTags.assertRetrieveTag("/t5", tag_t5_owner_o1); + ITUtilTags.assertRetrieveTag("/t6", tag_t6_owner_o1); + ITUtilTags.assertRetrieveTag("/t7", tag_t7_owner_o1); + ITUtilTags.assertRetrieveTag("/t8", tag_t8_owner_o1); + ITUtilTags.assertRetrieveTag("/t9", tag_t9_owner_o1); + ITUtilTags.assertRetrieveTag("/t10", tag_t10_owner_o1); + + ITUtilTags.assertRemoveTag("/t1"); + ITUtilTags.assertRemoveTag("/t2"); + ITUtilTags.assertRemoveTag("/t3"); + ITUtilTags.assertRemoveTag("/t4"); + ITUtilTags.assertRemoveTag("/t5"); + + ITUtilTags.assertListTags( + 5, tag_t10_owner_o1, tag_t6_owner_o1, tag_t7_owner_o1, tag_t8_owner_o1, tag_t9_owner_o1); + + ITUtilTags.assertRemoveTag("/t6"); + ITUtilTags.assertRemoveTag("/t7"); + ITUtilTags.assertRemoveTag("/t8"); + ITUtilTags.assertRemoveTag("/t9"); + ITUtilTags.assertRemoveTag("/t10"); + + ITUtilTags.assertListTags(0); + } catch (Exception e) { + fail(); } - + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ITTestFixture.java b/src/test/java/org/phoebus/channelfinder/docker/ITTestFixture.java index 7eee62e7..c0e4de9a 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ITTestFixture.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ITTestFixture.java @@ -21,7 +21,6 @@ import static org.junit.jupiter.api.Assertions.fail; import java.net.HttpURLConnection; - import org.phoebus.channelfinder.entity.Channel; import org.phoebus.channelfinder.entity.Property; import org.phoebus.channelfinder.entity.Tag; @@ -29,790 +28,753 @@ /** * Purpose to provide test fixture that can be used in multiple test classes and tests. * - *

- * Class is tightly coupled to ChannelFinder and Elasticsearch, and requires those to be up and running. - * Intended usage is by docker integration tests for ChannelFinder and Elasticsearch. + *

Class is tightly coupled to ChannelFinder and Elasticsearch, and requires those to be up and + * running. Intended usage is by docker integration tests for ChannelFinder and Elasticsearch. * * @author Lars Johansson */ public class ITTestFixture { - // Note - // ------------------------------------------------------------------------------------------------ - // About - // set up, tear down and tests (assert statements) to ensure test fixture as expected - // ------------------------------------------------------------------------------------------------ - // Content - // channels (10) - // ABC:DEF-GHI:JKL:001 - // ABC:DEF-GHI:JKL:002 - // ABC:DEF-GHI:JKL:003 - // ABC:DEF-GHI:JKL:010 - // ABC:DEF-GHI:JKL:011 - // ABC:DEF-XYZ:JKL:001 - // ABC:DEF-XYZ:JKL:002 - // ABC:DEF-XYZ:JKL:003 - // ABC:DEF-XYZ:JKL:010 - // ABC:DEF-XYZ:JKL:011 - // properties (4) - // domain (10 channels, values - cryo, power) - // element (10 channels, values - source, initial, radio, magnet, supra) - // type (10 channels, values - read, write, readwrite) - // cell (10 channels, values - block1, block2, block3, block4, block5) - // tags (4) - // archived ( 4 channels) - // handle_this ( 3 channels) - // noteworthy (10 channels) - // not_used ( 0 channels) - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - - // ---------------------------------------------------------------------------------------------------- - // test data - // channels, owner o1 - // ABC:DEF-GHI:JKL:001 - // ABC:DEF-GHI:JKL:002 - // ABC:DEF-GHI:JKL:003 - // ABC:DEF-GHI:JKL:010 - // ABC:DEF-GHI:JKL:011 - // ABC:DEF-XYZ:JKL:001 - // ABC:DEF-XYZ:JKL:002 - // ABC:DEF-XYZ:JKL:003 - // ABC:DEF-XYZ:JKL:010 - // ABC:DEF-XYZ:JKL:011 - - static Channel channel_ghi001; - static Channel channel_ghi002; - static Channel channel_ghi003; - static Channel channel_ghi010; - static Channel channel_ghi011; - static Channel channel_xyz001; - static Channel channel_xyz002; - static Channel channel_xyz003; - static Channel channel_xyz010; - static Channel channel_xyz011; - - static Channel channel_ghi001_properties_tags; - static Channel channel_ghi002_properties_tags; - static Channel channel_ghi003_properties_tags; - static Channel channel_ghi010_properties_tags; - static Channel channel_ghi011_properties_tags; - static Channel channel_xyz001_properties_tags; - static Channel channel_xyz002_properties_tags; - static Channel channel_xyz003_properties_tags; - static Channel channel_xyz010_properties_tags; - static Channel channel_xyz011_properties_tags; - - // convenience - static Channel[] channels_all_properties_tags; - - // test data - // properties, owner o1 - // domain - // element - // type - // cell - - static Property property_domain; - static Property property_element; - static Property property_type; - static Property property_cell; - - static Property property_domain_channels; - static Property property_element_channels; - static Property property_type_channels; - static Property property_cell_channels; - - // test data - // tags, owner o1 - // archived - // handle_this - // noteworthy - // not_used - - static Tag tag_archived; - static Tag tag_handle_this; - static Tag tag_noteworthy; - static Tag tag_not_used; - - static Tag tag_archived_channels; - static Tag tag_handle_this_channels; - static Tag tag_noteworthy_channels; - static Tag tag_not_used_channels; - - /** - * This class is not to be instantiated. - */ - private ITTestFixture() { - throw new IllegalStateException("Utility class"); - } - - /** - * Set up test fixture. - */ - static void setup() { - // note - // order of items is important - // to add properties to channels - // to add tags to channels - // for assert statements - - setupProperties(); - setupTags(); - setupChannels(); - - createProperties(); - createTags(); - createChannels(); - - setupAddPropertiesToChannels(); - setupAddTagsToChannels(); - - // list channels, of use for integration tests - channels_all_properties_tags = ITUtilChannels.assertListChannels(10); - } - - /** - * Tear down test fixture. - */ - static void tearDown() { - // note - // not necessary to remove items from channels in order to tear down (properties, tags) - // properties, tags, channels can be deleted regardless - - tearDownProperties(); - tearDownTags(); - tearDownChannels(); - } - - /** - * Set up test fixture, properties. - */ - private static void setupProperties() { - property_domain = new Property("domain", "o1"); - property_element = new Property("element", "o1"); - property_type = new Property("type", "o1"); - property_cell = new Property("cell", "o1"); - - property_domain_channels = new Property("domain", "o1"); - property_element_channels = new Property("element", "o1"); - property_type_channels = new Property("type", "o1"); - property_cell_channels = new Property("cell", "o1"); - } - - /** - * Set up test fixture, tags. - */ - private static void setupTags() { - tag_archived = new Tag("archived", "o1"); - tag_handle_this = new Tag("handle_this", "o1"); - tag_noteworthy = new Tag("noteworthy", "o1"); - tag_not_used = new Tag("not_used", "o1"); - - tag_archived_channels = new Tag("archived", "o1"); - tag_handle_this_channels = new Tag("handle_this", "o1"); - tag_noteworthy_channels = new Tag("noteworthy", "o1"); - tag_not_used_channels = new Tag("not_used", "o1"); - } - - /** - * Set up test fixture, channels. - */ - private static void setupChannels() { - channel_ghi001 = new Channel("ABC:DEF-GHI:JKL:001", "o1"); - channel_ghi002 = new Channel("ABC:DEF-GHI:JKL:002", "o1"); - channel_ghi003 = new Channel("ABC:DEF-GHI:JKL:003", "o1"); - channel_ghi010 = new Channel("ABC:DEF-GHI:JKL:010", "o1"); - channel_ghi011 = new Channel("ABC:DEF-GHI:JKL:011", "o1"); - channel_xyz001 = new Channel("ABC:DEF-XYZ:JKL:001", "o1"); - channel_xyz002 = new Channel("ABC:DEF-XYZ:JKL:002", "o1"); - channel_xyz003 = new Channel("ABC:DEF-XYZ:JKL:003", "o1"); - channel_xyz010 = new Channel("ABC:DEF-XYZ:JKL:010", "o1"); - channel_xyz011 = new Channel("ABC:DEF-XYZ:JKL:011", "o1"); - - channel_ghi001_properties_tags = new Channel("ABC:DEF-GHI:JKL:001", "o1"); - channel_ghi002_properties_tags = new Channel("ABC:DEF-GHI:JKL:002", "o1"); - channel_ghi003_properties_tags = new Channel("ABC:DEF-GHI:JKL:003", "o1"); - channel_ghi010_properties_tags = new Channel("ABC:DEF-GHI:JKL:010", "o1"); - channel_ghi011_properties_tags = new Channel("ABC:DEF-GHI:JKL:011", "o1"); - channel_xyz001_properties_tags = new Channel("ABC:DEF-XYZ:JKL:001", "o1"); - channel_xyz002_properties_tags = new Channel("ABC:DEF-XYZ:JKL:002", "o1"); - channel_xyz003_properties_tags = new Channel("ABC:DEF-XYZ:JKL:003", "o1"); - channel_xyz010_properties_tags = new Channel("ABC:DEF-XYZ:JKL:010", "o1"); - channel_xyz011_properties_tags = new Channel("ABC:DEF-XYZ:JKL:011", "o1"); + // Note + // + // ------------------------------------------------------------------------------------------------ + // About + // set up, tear down and tests (assert statements) to ensure test fixture as expected + // + // ------------------------------------------------------------------------------------------------ + // Content + // channels (10) + // ABC:DEF-GHI:JKL:001 + // ABC:DEF-GHI:JKL:002 + // ABC:DEF-GHI:JKL:003 + // ABC:DEF-GHI:JKL:010 + // ABC:DEF-GHI:JKL:011 + // ABC:DEF-XYZ:JKL:001 + // ABC:DEF-XYZ:JKL:002 + // ABC:DEF-XYZ:JKL:003 + // ABC:DEF-XYZ:JKL:010 + // ABC:DEF-XYZ:JKL:011 + // properties (4) + // domain (10 channels, values - cryo, power) + // element (10 channels, values - source, initial, radio, magnet, supra) + // type (10 channels, values - read, write, readwrite) + // cell (10 channels, values - block1, block2, block3, block4, block5) + // tags (4) + // archived ( 4 channels) + // handle_this ( 3 channels) + // noteworthy (10 channels) + // not_used ( 0 channels) + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + + // ---------------------------------------------------------------------------------------------------- + // test data + // channels, owner o1 + // ABC:DEF-GHI:JKL:001 + // ABC:DEF-GHI:JKL:002 + // ABC:DEF-GHI:JKL:003 + // ABC:DEF-GHI:JKL:010 + // ABC:DEF-GHI:JKL:011 + // ABC:DEF-XYZ:JKL:001 + // ABC:DEF-XYZ:JKL:002 + // ABC:DEF-XYZ:JKL:003 + // ABC:DEF-XYZ:JKL:010 + // ABC:DEF-XYZ:JKL:011 + + static Channel channel_ghi001; + static Channel channel_ghi002; + static Channel channel_ghi003; + static Channel channel_ghi010; + static Channel channel_ghi011; + static Channel channel_xyz001; + static Channel channel_xyz002; + static Channel channel_xyz003; + static Channel channel_xyz010; + static Channel channel_xyz011; + + static Channel channel_ghi001_properties_tags; + static Channel channel_ghi002_properties_tags; + static Channel channel_ghi003_properties_tags; + static Channel channel_ghi010_properties_tags; + static Channel channel_ghi011_properties_tags; + static Channel channel_xyz001_properties_tags; + static Channel channel_xyz002_properties_tags; + static Channel channel_xyz003_properties_tags; + static Channel channel_xyz010_properties_tags; + static Channel channel_xyz011_properties_tags; + + // convenience + static Channel[] channels_all_properties_tags; + + // test data + // properties, owner o1 + // domain + // element + // type + // cell + + static Property property_domain; + static Property property_element; + static Property property_type; + static Property property_cell; + + static Property property_domain_channels; + static Property property_element_channels; + static Property property_type_channels; + static Property property_cell_channels; + + // test data + // tags, owner o1 + // archived + // handle_this + // noteworthy + // not_used + + static Tag tag_archived; + static Tag tag_handle_this; + static Tag tag_noteworthy; + static Tag tag_not_used; + + static Tag tag_archived_channels; + static Tag tag_handle_this_channels; + static Tag tag_noteworthy_channels; + static Tag tag_not_used_channels; + + /** This class is not to be instantiated. */ + private ITTestFixture() { + throw new IllegalStateException("Utility class"); + } + + /** Set up test fixture. */ + static void setup() { + // note + // order of items is important + // to add properties to channels + // to add tags to channels + // for assert statements + + setupProperties(); + setupTags(); + setupChannels(); + + createProperties(); + createTags(); + createChannels(); + + setupAddPropertiesToChannels(); + setupAddTagsToChannels(); + + // list channels, of use for integration tests + channels_all_properties_tags = ITUtilChannels.assertListChannels(10); + } + + /** Tear down test fixture. */ + static void tearDown() { + // note + // not necessary to remove items from channels in order to tear down (properties, tags) + // properties, tags, channels can be deleted regardless + + tearDownProperties(); + tearDownTags(); + tearDownChannels(); + } + + /** Set up test fixture, properties. */ + private static void setupProperties() { + property_domain = new Property("domain", "o1"); + property_element = new Property("element", "o1"); + property_type = new Property("type", "o1"); + property_cell = new Property("cell", "o1"); + + property_domain_channels = new Property("domain", "o1"); + property_element_channels = new Property("element", "o1"); + property_type_channels = new Property("type", "o1"); + property_cell_channels = new Property("cell", "o1"); + } + + /** Set up test fixture, tags. */ + private static void setupTags() { + tag_archived = new Tag("archived", "o1"); + tag_handle_this = new Tag("handle_this", "o1"); + tag_noteworthy = new Tag("noteworthy", "o1"); + tag_not_used = new Tag("not_used", "o1"); + + tag_archived_channels = new Tag("archived", "o1"); + tag_handle_this_channels = new Tag("handle_this", "o1"); + tag_noteworthy_channels = new Tag("noteworthy", "o1"); + tag_not_used_channels = new Tag("not_used", "o1"); + } + + /** Set up test fixture, channels. */ + private static void setupChannels() { + channel_ghi001 = new Channel("ABC:DEF-GHI:JKL:001", "o1"); + channel_ghi002 = new Channel("ABC:DEF-GHI:JKL:002", "o1"); + channel_ghi003 = new Channel("ABC:DEF-GHI:JKL:003", "o1"); + channel_ghi010 = new Channel("ABC:DEF-GHI:JKL:010", "o1"); + channel_ghi011 = new Channel("ABC:DEF-GHI:JKL:011", "o1"); + channel_xyz001 = new Channel("ABC:DEF-XYZ:JKL:001", "o1"); + channel_xyz002 = new Channel("ABC:DEF-XYZ:JKL:002", "o1"); + channel_xyz003 = new Channel("ABC:DEF-XYZ:JKL:003", "o1"); + channel_xyz010 = new Channel("ABC:DEF-XYZ:JKL:010", "o1"); + channel_xyz011 = new Channel("ABC:DEF-XYZ:JKL:011", "o1"); + + channel_ghi001_properties_tags = new Channel("ABC:DEF-GHI:JKL:001", "o1"); + channel_ghi002_properties_tags = new Channel("ABC:DEF-GHI:JKL:002", "o1"); + channel_ghi003_properties_tags = new Channel("ABC:DEF-GHI:JKL:003", "o1"); + channel_ghi010_properties_tags = new Channel("ABC:DEF-GHI:JKL:010", "o1"); + channel_ghi011_properties_tags = new Channel("ABC:DEF-GHI:JKL:011", "o1"); + channel_xyz001_properties_tags = new Channel("ABC:DEF-XYZ:JKL:001", "o1"); + channel_xyz002_properties_tags = new Channel("ABC:DEF-XYZ:JKL:002", "o1"); + channel_xyz003_properties_tags = new Channel("ABC:DEF-XYZ:JKL:003", "o1"); + channel_xyz010_properties_tags = new Channel("ABC:DEF-XYZ:JKL:010", "o1"); + channel_xyz011_properties_tags = new Channel("ABC:DEF-XYZ:JKL:011", "o1"); + } + + /** Create test fixture, properties. */ + private static void createProperties() { + Property[] properties_4 = + new Property[] {property_domain, property_element, property_type, property_cell}; + + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- + + ITUtilProperties.assertListProperties(0); + + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- + + ITUtilProperties.assertCreateReplaceProperties("", properties_4); + + ITUtilProperties.assertRetrieveProperty("/domain", property_domain); + ITUtilProperties.assertRetrieveProperty("/domain?withChannels=true", property_domain); + ITUtilProperties.assertRetrieveProperty("/domain?withChannels=false", property_domain); + + ITUtilProperties.assertRetrieveProperty("/element", property_element); + ITUtilProperties.assertRetrieveProperty("/element?withChannels=true", property_element); + ITUtilProperties.assertRetrieveProperty("/element?withChannels=false", property_element); + + ITUtilProperties.assertRetrieveProperty("/type", property_type); + ITUtilProperties.assertRetrieveProperty("/type?withChannels=true", property_type); + ITUtilProperties.assertRetrieveProperty("/type?withChannels=false", property_type); + + ITUtilProperties.assertRetrieveProperty("/cell", property_cell); + ITUtilProperties.assertRetrieveProperty("/cell?withChannels=true", property_cell); + ITUtilProperties.assertRetrieveProperty("/cell?withChannels=false", property_cell); + + ITUtilProperties.assertListProperties( + 4, property_cell, property_domain, property_element, property_type); + } catch (Exception e) { + fail(); } + } - /** - * Create test fixture, properties. - */ - private static void createProperties() { - Property[] properties_4 = new Property[] { - property_domain, - property_element, - property_type, - property_cell - }; + /** Create test fixture, tags. */ + private static void createTags() { + Tag[] tags_4 = new Tag[] {tag_archived, tag_handle_this, tag_noteworthy, tag_not_used}; - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- - ITUtilProperties.assertListProperties(0); + ITUtilTags.assertListTags(0); - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- - ITUtilProperties.assertCreateReplaceProperties("", properties_4); + ITUtilTags.assertCreateReplaceTags("", tags_4); - ITUtilProperties.assertRetrieveProperty("/domain", property_domain); - ITUtilProperties.assertRetrieveProperty("/domain?withChannels=true", property_domain); - ITUtilProperties.assertRetrieveProperty("/domain?withChannels=false", property_domain); + ITUtilTags.assertRetrieveTag("/archived", tag_archived); + ITUtilTags.assertRetrieveTag("/archived?withChannels=true", tag_archived); + ITUtilTags.assertRetrieveTag("/archived?withChannels=false", tag_archived); - ITUtilProperties.assertRetrieveProperty("/element", property_element); - ITUtilProperties.assertRetrieveProperty("/element?withChannels=true", property_element); - ITUtilProperties.assertRetrieveProperty("/element?withChannels=false", property_element); + ITUtilTags.assertRetrieveTag("/handle_this", tag_handle_this); + ITUtilTags.assertRetrieveTag("/handle_this?withChannels=true", tag_handle_this); + ITUtilTags.assertRetrieveTag("/handle_this?withChannels=false", tag_handle_this); - ITUtilProperties.assertRetrieveProperty("/type", property_type); - ITUtilProperties.assertRetrieveProperty("/type?withChannels=true", property_type); - ITUtilProperties.assertRetrieveProperty("/type?withChannels=false", property_type); + ITUtilTags.assertRetrieveTag("/noteworthy", tag_noteworthy); + ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=true", tag_noteworthy); + ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=false", tag_noteworthy); - ITUtilProperties.assertRetrieveProperty("/cell", property_cell); - ITUtilProperties.assertRetrieveProperty("/cell?withChannels=true", property_cell); - ITUtilProperties.assertRetrieveProperty("/cell?withChannels=false", property_cell); + ITUtilTags.assertRetrieveTag("/not_used", tag_not_used); + ITUtilTags.assertRetrieveTag("/not_used?withChannels=true", tag_not_used); + ITUtilTags.assertRetrieveTag("/not_used?withChannels=false", tag_not_used); - ITUtilProperties.assertListProperties(4, - property_cell, - property_domain, - property_element, - property_type); - } catch (Exception e) { - fail(); - } + ITUtilTags.assertListTags(4, tag_archived, tag_handle_this, tag_not_used, tag_noteworthy); + } catch (Exception e) { + fail(); } - - /** - * Create test fixture, tags. - */ - private static void createTags() { - Tag[] tags_4 = new Tag[] { - tag_archived, - tag_handle_this, - tag_noteworthy, - tag_not_used + } + + /** Create test fixture, channels. */ + private static void createChannels() { + Channel[] channels_10 = + new Channel[] { + channel_ghi001, + channel_ghi002, + channel_ghi003, + channel_ghi010, + channel_ghi011, + channel_xyz001, + channel_xyz002, + channel_xyz003, + channel_xyz010, + channel_xyz011 }; - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- - - ITUtilTags.assertListTags(0); - - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- - - ITUtilTags.assertCreateReplaceTags("", tags_4); - - ITUtilTags.assertRetrieveTag("/archived", tag_archived); - ITUtilTags.assertRetrieveTag("/archived?withChannels=true", tag_archived); - ITUtilTags.assertRetrieveTag("/archived?withChannels=false", tag_archived); - - ITUtilTags.assertRetrieveTag("/handle_this", tag_handle_this); - ITUtilTags.assertRetrieveTag("/handle_this?withChannels=true", tag_handle_this); - ITUtilTags.assertRetrieveTag("/handle_this?withChannels=false", tag_handle_this); - - ITUtilTags.assertRetrieveTag("/noteworthy", tag_noteworthy); - ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=true", tag_noteworthy); - ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=false", tag_noteworthy); - - ITUtilTags.assertRetrieveTag("/not_used", tag_not_used); - ITUtilTags.assertRetrieveTag("/not_used?withChannels=true", tag_not_used); - ITUtilTags.assertRetrieveTag("/not_used?withChannels=false", tag_not_used); - - ITUtilTags.assertListTags(4, - tag_archived, - tag_handle_this, - tag_not_used, - tag_noteworthy); - } catch (Exception e) { - fail(); - } + try { + // -------------------------------------------------------------------------------- + // clean start + // -------------------------------------------------------------------------------- + + ITUtilChannels.assertListChannels(0); + + // -------------------------------------------------------------------------------- + // put + // -------------------------------------------------------------------------------- + + ITUtilChannels.assertCreateReplaceMultipleChannels("", channels_10); + + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:001", ITTestFixture.channel_ghi001_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:002", ITTestFixture.channel_ghi002_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:003", ITTestFixture.channel_ghi003_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:010", ITTestFixture.channel_ghi010_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-GHI:JKL:011", ITTestFixture.channel_ghi011_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:001", ITTestFixture.channel_xyz001_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:002", ITTestFixture.channel_xyz002_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:003", ITTestFixture.channel_xyz003_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:010", ITTestFixture.channel_xyz010_properties_tags); + ITUtilChannels.assertListChannels( + "?~name=ABC:DEF-XYZ:JKL:011", ITTestFixture.channel_xyz011_properties_tags); + + ITUtilChannels.assertListChannels( + 10, + channel_ghi001, + channel_ghi002, + channel_ghi003, + channel_ghi010, + channel_ghi011, + channel_xyz001, + channel_xyz002, + channel_xyz003, + channel_xyz010, + channel_xyz011); + } catch (Exception e) { + fail(); } - - /** - * Create test fixture, channels. - */ - private static void createChannels() { - Channel[] channels_10 = new Channel[] { - channel_ghi001, - channel_ghi002, - channel_ghi003, - channel_ghi010, - channel_ghi011, - channel_xyz001, - channel_xyz002, - channel_xyz003, - channel_xyz010, - channel_xyz011 - }; - - try { - // -------------------------------------------------------------------------------- - // clean start - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertListChannels(0); - - // -------------------------------------------------------------------------------- - // put - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertCreateReplaceMultipleChannels("", channels_10); - - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:001", ITTestFixture.channel_ghi001_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:002", ITTestFixture.channel_ghi002_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:003", ITTestFixture.channel_ghi003_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:010", ITTestFixture.channel_ghi010_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-GHI:JKL:011", ITTestFixture.channel_ghi011_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:001", ITTestFixture.channel_xyz001_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:002", ITTestFixture.channel_xyz002_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:003", ITTestFixture.channel_xyz003_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:010", ITTestFixture.channel_xyz010_properties_tags); - ITUtilChannels.assertListChannels("?~name=ABC:DEF-XYZ:JKL:011", ITTestFixture.channel_xyz011_properties_tags); - - ITUtilChannels.assertListChannels(10, - channel_ghi001, - channel_ghi002, - channel_ghi003, - channel_ghi010, - channel_ghi011, - channel_xyz001, - channel_xyz002, - channel_xyz003, - channel_xyz010, - channel_xyz011); - } catch (Exception e) { - fail(); - } + } + + /** Set up test fixture, add properties to channels. */ + private static void setupAddPropertiesToChannels() { + // properties + // domain + // element + // type + // cell + + try { + // -------------------------------------------------------------------------------- + // add property (domain) to multiple channels + // -------------------------------------------------------------------------------- + + Property property_domain_cryo = + new Property(property_domain.getName(), property_domain.getOwner(), "cryo"); + Property property_domain_power = + new Property(property_domain.getName(), property_domain.getOwner(), "power"); + + channel_ghi001_properties_tags.addProperty(property_domain_cryo); + channel_ghi002_properties_tags.addProperty(property_domain_cryo); + channel_ghi003_properties_tags.addProperty(property_domain_cryo); + channel_ghi010_properties_tags.addProperty(property_domain_cryo); + channel_ghi011_properties_tags.addProperty(property_domain_cryo); + channel_xyz001_properties_tags.addProperty(property_domain_power); + channel_xyz002_properties_tags.addProperty(property_domain_power); + channel_xyz003_properties_tags.addProperty(property_domain_power); + channel_xyz010_properties_tags.addProperty(property_domain_power); + channel_xyz011_properties_tags.addProperty(property_domain_power); + property_domain_channels.getChannels().add(channel_ghi001_properties_tags); + property_domain_channels.getChannels().add(channel_ghi002_properties_tags); + property_domain_channels.getChannels().add(channel_ghi003_properties_tags); + property_domain_channels.getChannels().add(channel_ghi010_properties_tags); + property_domain_channels.getChannels().add(channel_ghi011_properties_tags); + property_domain_channels.getChannels().add(channel_xyz001_properties_tags); + property_domain_channels.getChannels().add(channel_xyz002_properties_tags); + property_domain_channels.getChannels().add(channel_xyz003_properties_tags); + property_domain_channels.getChannels().add(channel_xyz010_properties_tags); + property_domain_channels.getChannels().add(channel_xyz011_properties_tags); + + ITUtilProperties.assertAddPropertyMultipleChannels("/domain", property_domain_channels); + + ITUtilProperties.assertListProperties( + 4, property_cell, property_domain, property_element, property_type); + + ITUtilProperties.assertRetrieveProperty("/domain", property_domain_channels); + ITUtilProperties.assertRetrieveProperty( + "/domain?withChannels=true", property_domain_channels); + ITUtilProperties.assertRetrieveProperty("/domain?withChannels=false", property_domain); + + // -------------------------------------------------------------------------------- + // add property (element) to multiple channels + // -------------------------------------------------------------------------------- + + Property property_element_source = + new Property(property_element.getName(), property_element.getOwner(), "source"); + Property property_element_initial = + new Property(property_element.getName(), property_element.getOwner(), "initial"); + Property property_element_radio = + new Property(property_element.getName(), property_element.getOwner(), "radio"); + Property property_element_magnet = + new Property(property_element.getName(), property_element.getOwner(), "magnet"); + Property property_element_supra = + new Property(property_element.getName(), property_element.getOwner(), "supra"); + + channel_ghi001_properties_tags.addProperty(property_element_source); + channel_ghi002_properties_tags.addProperty(property_element_initial); + channel_ghi003_properties_tags.addProperty(property_element_radio); + channel_ghi010_properties_tags.addProperty(property_element_magnet); + channel_ghi011_properties_tags.addProperty(property_element_supra); + channel_xyz001_properties_tags.addProperty(property_element_source); + channel_xyz002_properties_tags.addProperty(property_element_initial); + channel_xyz003_properties_tags.addProperty(property_element_radio); + channel_xyz010_properties_tags.addProperty(property_element_magnet); + channel_xyz011_properties_tags.addProperty(property_element_supra); + property_element_channels.getChannels().add(channel_ghi001_properties_tags); + property_element_channels.getChannels().add(channel_ghi002_properties_tags); + property_element_channels.getChannels().add(channel_ghi003_properties_tags); + property_element_channels.getChannels().add(channel_ghi010_properties_tags); + property_element_channels.getChannels().add(channel_ghi011_properties_tags); + property_element_channels.getChannels().add(channel_xyz001_properties_tags); + property_element_channels.getChannels().add(channel_xyz002_properties_tags); + property_element_channels.getChannels().add(channel_xyz003_properties_tags); + property_element_channels.getChannels().add(channel_xyz010_properties_tags); + property_element_channels.getChannels().add(channel_xyz011_properties_tags); + + ITUtilProperties.assertAddPropertyMultipleChannels("/element", property_element_channels); + + ITUtilProperties.assertListProperties( + 4, property_cell, property_domain, property_element, property_type); + + ITUtilProperties.assertRetrieveProperty("/element", property_element_channels); + ITUtilProperties.assertRetrieveProperty( + "/element?withChannels=true", property_element_channels); + ITUtilProperties.assertRetrieveProperty("/element?withChannels=false", property_element); + + // -------------------------------------------------------------------------------- + // add property (type) to multiple channels + // -------------------------------------------------------------------------------- + + Property property_type_read = + new Property(property_type.getName(), property_type.getOwner(), "read"); + Property property_type_write = + new Property(property_type.getName(), property_type.getOwner(), "write"); + Property property_type_readwrite = + new Property(property_type.getName(), property_type.getOwner(), "readwrite"); + + channel_ghi001_properties_tags.addProperty(property_type_read); + channel_ghi002_properties_tags.addProperty(property_type_read); + channel_ghi003_properties_tags.addProperty(property_type_write); + channel_ghi010_properties_tags.addProperty(property_type_write); + channel_ghi011_properties_tags.addProperty(property_type_readwrite); + channel_xyz001_properties_tags.addProperty(property_type_readwrite); + channel_xyz002_properties_tags.addProperty(property_type_write); + channel_xyz003_properties_tags.addProperty(property_type_write); + channel_xyz010_properties_tags.addProperty(property_type_read); + channel_xyz011_properties_tags.addProperty(property_type_read); + property_type_channels.getChannels().add(channel_ghi001_properties_tags); + property_type_channels.getChannels().add(channel_ghi002_properties_tags); + property_type_channels.getChannels().add(channel_ghi003_properties_tags); + property_type_channels.getChannels().add(channel_ghi010_properties_tags); + property_type_channels.getChannels().add(channel_ghi011_properties_tags); + property_type_channels.getChannels().add(channel_xyz001_properties_tags); + property_type_channels.getChannels().add(channel_xyz002_properties_tags); + property_type_channels.getChannels().add(channel_xyz003_properties_tags); + property_type_channels.getChannels().add(channel_xyz010_properties_tags); + property_type_channels.getChannels().add(channel_xyz011_properties_tags); + + ITUtilProperties.assertAddPropertyMultipleChannels("/type", property_type_channels); + + ITUtilProperties.assertListProperties( + 4, property_cell, property_domain, property_element, property_type); + + ITUtilProperties.assertRetrieveProperty("/type", property_type_channels); + ITUtilProperties.assertRetrieveProperty("/type?withChannels=true", property_type_channels); + ITUtilProperties.assertRetrieveProperty("/type?withChannels=false", property_type); + + // -------------------------------------------------------------------------------- + // add property (cell) to multiple channels + // -------------------------------------------------------------------------------- + + Property property_cell_block1 = + new Property(property_cell.getName(), property_cell.getOwner(), "block1"); + Property property_cell_block2 = + new Property(property_cell.getName(), property_cell.getOwner(), "block2"); + Property property_cell_block3 = + new Property(property_cell.getName(), property_cell.getOwner(), "block3"); + Property property_cell_block4 = + new Property(property_cell.getName(), property_cell.getOwner(), "block4"); + Property property_cell_block5 = + new Property(property_cell.getName(), property_cell.getOwner(), "block5"); + + channel_ghi001_properties_tags.addProperty(property_cell_block1); + channel_ghi002_properties_tags.addProperty(property_cell_block2); + channel_ghi003_properties_tags.addProperty(property_cell_block3); + channel_ghi010_properties_tags.addProperty(property_cell_block4); + channel_ghi011_properties_tags.addProperty(property_cell_block5); + channel_xyz001_properties_tags.addProperty(property_cell_block1); + channel_xyz002_properties_tags.addProperty(property_cell_block2); + channel_xyz003_properties_tags.addProperty(property_cell_block3); + channel_xyz010_properties_tags.addProperty(property_cell_block4); + channel_xyz011_properties_tags.addProperty(property_cell_block5); + property_cell_channels.getChannels().add(channel_ghi001_properties_tags); + property_cell_channels.getChannels().add(channel_ghi002_properties_tags); + property_cell_channels.getChannels().add(channel_ghi003_properties_tags); + property_cell_channels.getChannels().add(channel_ghi010_properties_tags); + property_cell_channels.getChannels().add(channel_ghi011_properties_tags); + property_cell_channels.getChannels().add(channel_xyz001_properties_tags); + property_cell_channels.getChannels().add(channel_xyz002_properties_tags); + property_cell_channels.getChannels().add(channel_xyz003_properties_tags); + property_cell_channels.getChannels().add(channel_xyz010_properties_tags); + property_cell_channels.getChannels().add(channel_xyz011_properties_tags); + + ITUtilProperties.assertAddPropertyMultipleChannels("/cell", property_cell_channels); + + ITUtilProperties.assertListProperties( + 4, property_cell, property_domain, property_element, property_type); + + ITUtilProperties.assertRetrieveProperty("/cell", property_cell_channels); + ITUtilProperties.assertRetrieveProperty("/cell?withChannels=true", property_cell_channels); + ITUtilProperties.assertRetrieveProperty("/cell?withChannels=false", property_cell); + + // -------------------------------------------------------------------------------- + // check channels + // -------------------------------------------------------------------------------- + + ITUtilChannels.assertListChannels(10); + + // ensure that channel is there, value not important at this stage + ITUtilChannels.assertRetrieveChannel("/ABC:DEF-GHI:JKL:002", HttpURLConnection.HTTP_OK); + } catch (Exception e) { + fail(); } - - /** - * Set up test fixture, add properties to channels. - */ - private static void setupAddPropertiesToChannels() { - // properties - // domain - // element - // type - // cell - - try { - // -------------------------------------------------------------------------------- - // add property (domain) to multiple channels - // -------------------------------------------------------------------------------- - - Property property_domain_cryo = new Property(property_domain.getName(), property_domain.getOwner(), "cryo"); - Property property_domain_power = new Property(property_domain.getName(), property_domain.getOwner(), "power"); - - channel_ghi001_properties_tags.addProperty(property_domain_cryo); - channel_ghi002_properties_tags.addProperty(property_domain_cryo); - channel_ghi003_properties_tags.addProperty(property_domain_cryo); - channel_ghi010_properties_tags.addProperty(property_domain_cryo); - channel_ghi011_properties_tags.addProperty(property_domain_cryo); - channel_xyz001_properties_tags.addProperty(property_domain_power); - channel_xyz002_properties_tags.addProperty(property_domain_power); - channel_xyz003_properties_tags.addProperty(property_domain_power); - channel_xyz010_properties_tags.addProperty(property_domain_power); - channel_xyz011_properties_tags.addProperty(property_domain_power); - property_domain_channels.getChannels().add(channel_ghi001_properties_tags); - property_domain_channels.getChannels().add(channel_ghi002_properties_tags); - property_domain_channels.getChannels().add(channel_ghi003_properties_tags); - property_domain_channels.getChannels().add(channel_ghi010_properties_tags); - property_domain_channels.getChannels().add(channel_ghi011_properties_tags); - property_domain_channels.getChannels().add(channel_xyz001_properties_tags); - property_domain_channels.getChannels().add(channel_xyz002_properties_tags); - property_domain_channels.getChannels().add(channel_xyz003_properties_tags); - property_domain_channels.getChannels().add(channel_xyz010_properties_tags); - property_domain_channels.getChannels().add(channel_xyz011_properties_tags); - - ITUtilProperties.assertAddPropertyMultipleChannels("/domain", property_domain_channels); - - ITUtilProperties.assertListProperties(4, - property_cell, - property_domain, - property_element, - property_type); - - ITUtilProperties.assertRetrieveProperty("/domain", property_domain_channels); - ITUtilProperties.assertRetrieveProperty("/domain?withChannels=true", property_domain_channels); - ITUtilProperties.assertRetrieveProperty("/domain?withChannels=false", property_domain); - - // -------------------------------------------------------------------------------- - // add property (element) to multiple channels - // -------------------------------------------------------------------------------- - - Property property_element_source = new Property(property_element.getName(), property_element.getOwner(), "source"); - Property property_element_initial = new Property(property_element.getName(), property_element.getOwner(), "initial"); - Property property_element_radio = new Property(property_element.getName(), property_element.getOwner(), "radio"); - Property property_element_magnet = new Property(property_element.getName(), property_element.getOwner(), "magnet"); - Property property_element_supra = new Property(property_element.getName(), property_element.getOwner(), "supra"); - - channel_ghi001_properties_tags.addProperty(property_element_source); - channel_ghi002_properties_tags.addProperty(property_element_initial); - channel_ghi003_properties_tags.addProperty(property_element_radio); - channel_ghi010_properties_tags.addProperty(property_element_magnet); - channel_ghi011_properties_tags.addProperty(property_element_supra); - channel_xyz001_properties_tags.addProperty(property_element_source); - channel_xyz002_properties_tags.addProperty(property_element_initial); - channel_xyz003_properties_tags.addProperty(property_element_radio); - channel_xyz010_properties_tags.addProperty(property_element_magnet); - channel_xyz011_properties_tags.addProperty(property_element_supra); - property_element_channels.getChannels().add(channel_ghi001_properties_tags); - property_element_channels.getChannels().add(channel_ghi002_properties_tags); - property_element_channels.getChannels().add(channel_ghi003_properties_tags); - property_element_channels.getChannels().add(channel_ghi010_properties_tags); - property_element_channels.getChannels().add(channel_ghi011_properties_tags); - property_element_channels.getChannels().add(channel_xyz001_properties_tags); - property_element_channels.getChannels().add(channel_xyz002_properties_tags); - property_element_channels.getChannels().add(channel_xyz003_properties_tags); - property_element_channels.getChannels().add(channel_xyz010_properties_tags); - property_element_channels.getChannels().add(channel_xyz011_properties_tags); - - ITUtilProperties.assertAddPropertyMultipleChannels("/element", property_element_channels); - - ITUtilProperties.assertListProperties(4, - property_cell, - property_domain, - property_element, - property_type); - - ITUtilProperties.assertRetrieveProperty("/element", property_element_channels); - ITUtilProperties.assertRetrieveProperty("/element?withChannels=true", property_element_channels); - ITUtilProperties.assertRetrieveProperty("/element?withChannels=false", property_element); - - // -------------------------------------------------------------------------------- - // add property (type) to multiple channels - // -------------------------------------------------------------------------------- - - Property property_type_read = new Property(property_type.getName(), property_type.getOwner(), "read"); - Property property_type_write = new Property(property_type.getName(), property_type.getOwner(), "write"); - Property property_type_readwrite = new Property(property_type.getName(), property_type.getOwner(), "readwrite"); - - channel_ghi001_properties_tags.addProperty(property_type_read); - channel_ghi002_properties_tags.addProperty(property_type_read); - channel_ghi003_properties_tags.addProperty(property_type_write); - channel_ghi010_properties_tags.addProperty(property_type_write); - channel_ghi011_properties_tags.addProperty(property_type_readwrite); - channel_xyz001_properties_tags.addProperty(property_type_readwrite); - channel_xyz002_properties_tags.addProperty(property_type_write); - channel_xyz003_properties_tags.addProperty(property_type_write); - channel_xyz010_properties_tags.addProperty(property_type_read); - channel_xyz011_properties_tags.addProperty(property_type_read); - property_type_channels.getChannels().add(channel_ghi001_properties_tags); - property_type_channels.getChannels().add(channel_ghi002_properties_tags); - property_type_channels.getChannels().add(channel_ghi003_properties_tags); - property_type_channels.getChannels().add(channel_ghi010_properties_tags); - property_type_channels.getChannels().add(channel_ghi011_properties_tags); - property_type_channels.getChannels().add(channel_xyz001_properties_tags); - property_type_channels.getChannels().add(channel_xyz002_properties_tags); - property_type_channels.getChannels().add(channel_xyz003_properties_tags); - property_type_channels.getChannels().add(channel_xyz010_properties_tags); - property_type_channels.getChannels().add(channel_xyz011_properties_tags); - - ITUtilProperties.assertAddPropertyMultipleChannels("/type", property_type_channels); - - ITUtilProperties.assertListProperties(4, - property_cell, - property_domain, - property_element, - property_type); - - ITUtilProperties.assertRetrieveProperty("/type", property_type_channels); - ITUtilProperties.assertRetrieveProperty("/type?withChannels=true", property_type_channels); - ITUtilProperties.assertRetrieveProperty("/type?withChannels=false", property_type); - - // -------------------------------------------------------------------------------- - // add property (cell) to multiple channels - // -------------------------------------------------------------------------------- - - Property property_cell_block1 = new Property(property_cell.getName(), property_cell.getOwner(), "block1"); - Property property_cell_block2 = new Property(property_cell.getName(), property_cell.getOwner(), "block2"); - Property property_cell_block3 = new Property(property_cell.getName(), property_cell.getOwner(), "block3"); - Property property_cell_block4 = new Property(property_cell.getName(), property_cell.getOwner(), "block4"); - Property property_cell_block5 = new Property(property_cell.getName(), property_cell.getOwner(), "block5"); - - channel_ghi001_properties_tags.addProperty(property_cell_block1); - channel_ghi002_properties_tags.addProperty(property_cell_block2); - channel_ghi003_properties_tags.addProperty(property_cell_block3); - channel_ghi010_properties_tags.addProperty(property_cell_block4); - channel_ghi011_properties_tags.addProperty(property_cell_block5); - channel_xyz001_properties_tags.addProperty(property_cell_block1); - channel_xyz002_properties_tags.addProperty(property_cell_block2); - channel_xyz003_properties_tags.addProperty(property_cell_block3); - channel_xyz010_properties_tags.addProperty(property_cell_block4); - channel_xyz011_properties_tags.addProperty(property_cell_block5); - property_cell_channels.getChannels().add(channel_ghi001_properties_tags); - property_cell_channels.getChannels().add(channel_ghi002_properties_tags); - property_cell_channels.getChannels().add(channel_ghi003_properties_tags); - property_cell_channels.getChannels().add(channel_ghi010_properties_tags); - property_cell_channels.getChannels().add(channel_ghi011_properties_tags); - property_cell_channels.getChannels().add(channel_xyz001_properties_tags); - property_cell_channels.getChannels().add(channel_xyz002_properties_tags); - property_cell_channels.getChannels().add(channel_xyz003_properties_tags); - property_cell_channels.getChannels().add(channel_xyz010_properties_tags); - property_cell_channels.getChannels().add(channel_xyz011_properties_tags); - - ITUtilProperties.assertAddPropertyMultipleChannels("/cell", property_cell_channels); - - ITUtilProperties.assertListProperties(4, - property_cell, - property_domain, - property_element, - property_type); - - ITUtilProperties.assertRetrieveProperty("/cell", property_cell_channels); - ITUtilProperties.assertRetrieveProperty("/cell?withChannels=true", property_cell_channels); - ITUtilProperties.assertRetrieveProperty("/cell?withChannels=false", property_cell); - - // -------------------------------------------------------------------------------- - // check channels - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertListChannels(10); - - // ensure that channel is there, value not important at this stage - ITUtilChannels.assertRetrieveChannel("/ABC:DEF-GHI:JKL:002", HttpURLConnection.HTTP_OK); - } catch (Exception e) { - fail(); - } + } + + /** Set up test fixture, add tags to channels. */ + private static void setupAddTagsToChannels() { + // tags + // archived + // handle_this + // noteworthy + // not_used (NOT add tag (not_used) to any channel) + + try { + // -------------------------------------------------------------------------------- + // add tag (archived) to multiple channels + // -------------------------------------------------------------------------------- + + channel_ghi001_properties_tags.addTag(tag_archived); + channel_ghi002_properties_tags.addTag(tag_archived); + channel_xyz001_properties_tags.addTag(tag_archived); + channel_xyz002_properties_tags.addTag(tag_archived); + tag_archived_channels.getChannels().add(channel_ghi001_properties_tags); + tag_archived_channels.getChannels().add(channel_ghi002_properties_tags); + tag_archived_channels.getChannels().add(channel_xyz001_properties_tags); + tag_archived_channels.getChannels().add(channel_xyz002_properties_tags); + + ITUtilTags.assertAddTagMultipleChannels("/archived", tag_archived_channels); + + ITUtilTags.assertListTags(4, tag_archived, tag_handle_this, tag_not_used, tag_noteworthy); + + ITUtilTags.assertRetrieveTag("/archived", tag_archived_channels); + ITUtilTags.assertRetrieveTag("/archived?withChannels=true", tag_archived_channels); + ITUtilTags.assertRetrieveTag("/archived?withChannels=false", tag_archived); + + // -------------------------------------------------------------------------------- + // add tag (handle_this) to multiple channels + // -------------------------------------------------------------------------------- + + channel_ghi010_properties_tags.addTag(tag_handle_this); + channel_ghi011_properties_tags.addTag(tag_handle_this); + channel_xyz001_properties_tags.addTag(tag_handle_this); + tag_handle_this_channels.getChannels().add(channel_ghi010_properties_tags); + tag_handle_this_channels.getChannels().add(channel_ghi011_properties_tags); + tag_handle_this_channels.getChannels().add(channel_xyz001_properties_tags); + + ITUtilTags.assertAddTagMultipleChannels("/handle_this", tag_handle_this_channels); + + ITUtilTags.assertListTags(4, tag_archived, tag_handle_this, tag_not_used, tag_noteworthy); + + ITUtilTags.assertRetrieveTag("/handle_this", tag_handle_this_channels); + ITUtilTags.assertRetrieveTag("/handle_this?withChannels=true", tag_handle_this_channels); + ITUtilTags.assertRetrieveTag("/handle_this?withChannels=false", tag_handle_this); + + // -------------------------------------------------------------------------------- + // add tag (noteworthy) to multiple channels + // -------------------------------------------------------------------------------- + + channel_ghi001_properties_tags.addTag(tag_noteworthy); + channel_ghi002_properties_tags.addTag(tag_noteworthy); + channel_ghi003_properties_tags.addTag(tag_noteworthy); + channel_ghi010_properties_tags.addTag(tag_noteworthy); + channel_ghi011_properties_tags.addTag(tag_noteworthy); + channel_xyz001_properties_tags.addTag(tag_noteworthy); + channel_xyz002_properties_tags.addTag(tag_noteworthy); + channel_xyz003_properties_tags.addTag(tag_noteworthy); + channel_xyz010_properties_tags.addTag(tag_noteworthy); + channel_xyz011_properties_tags.addTag(tag_noteworthy); + tag_noteworthy_channels.getChannels().add(channel_ghi001_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_ghi002_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_ghi003_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_ghi010_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_ghi011_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_xyz001_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_xyz002_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_xyz003_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_xyz010_properties_tags); + tag_noteworthy_channels.getChannels().add(channel_xyz011_properties_tags); + + ITUtilTags.assertAddTagMultipleChannels("/noteworthy", tag_noteworthy_channels); + + ITUtilTags.assertListTags(4, tag_archived, tag_handle_this, tag_not_used, tag_noteworthy); + + ITUtilTags.assertRetrieveTag("/noteworthy", tag_noteworthy_channels); + ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=true", tag_noteworthy_channels); + ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=false", tag_noteworthy); + + // -------------------------------------------------------------------------------- + // NOT add tag (not_used) to any channel + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // check channels + // -------------------------------------------------------------------------------- + + ITUtilChannels.assertListChannels(10); + + // ensure that channel is there, value not important at this stage + ITUtilChannels.assertRetrieveChannel("/ABC:DEF-XYZ:JKL:011", HttpURLConnection.HTTP_OK); + } catch (Exception e) { + fail(); } - - /** - * Set up test fixture, add tags to channels. - */ - private static void setupAddTagsToChannels() { - // tags - // archived - // handle_this - // noteworthy - // not_used (NOT add tag (not_used) to any channel) - - try { - // -------------------------------------------------------------------------------- - // add tag (archived) to multiple channels - // -------------------------------------------------------------------------------- - - channel_ghi001_properties_tags.addTag(tag_archived); - channel_ghi002_properties_tags.addTag(tag_archived); - channel_xyz001_properties_tags.addTag(tag_archived); - channel_xyz002_properties_tags.addTag(tag_archived); - tag_archived_channels.getChannels().add(channel_ghi001_properties_tags); - tag_archived_channels.getChannels().add(channel_ghi002_properties_tags); - tag_archived_channels.getChannels().add(channel_xyz001_properties_tags); - tag_archived_channels.getChannels().add(channel_xyz002_properties_tags); - - ITUtilTags.assertAddTagMultipleChannels("/archived", tag_archived_channels); - - ITUtilTags.assertListTags(4, - tag_archived, - tag_handle_this, - tag_not_used, - tag_noteworthy); - - ITUtilTags.assertRetrieveTag("/archived", tag_archived_channels); - ITUtilTags.assertRetrieveTag("/archived?withChannels=true", tag_archived_channels); - ITUtilTags.assertRetrieveTag("/archived?withChannels=false", tag_archived); - - // -------------------------------------------------------------------------------- - // add tag (handle_this) to multiple channels - // -------------------------------------------------------------------------------- - - channel_ghi010_properties_tags.addTag(tag_handle_this); - channel_ghi011_properties_tags.addTag(tag_handle_this); - channel_xyz001_properties_tags.addTag(tag_handle_this); - tag_handle_this_channels.getChannels().add(channel_ghi010_properties_tags); - tag_handle_this_channels.getChannels().add(channel_ghi011_properties_tags); - tag_handle_this_channels.getChannels().add(channel_xyz001_properties_tags); - - ITUtilTags.assertAddTagMultipleChannels("/handle_this", tag_handle_this_channels); - - ITUtilTags.assertListTags(4, - tag_archived, - tag_handle_this, - tag_not_used, - tag_noteworthy); - - ITUtilTags.assertRetrieveTag("/handle_this", tag_handle_this_channels); - ITUtilTags.assertRetrieveTag("/handle_this?withChannels=true", tag_handle_this_channels); - ITUtilTags.assertRetrieveTag("/handle_this?withChannels=false", tag_handle_this); - - // -------------------------------------------------------------------------------- - // add tag (noteworthy) to multiple channels - // -------------------------------------------------------------------------------- - - channel_ghi001_properties_tags.addTag(tag_noteworthy); - channel_ghi002_properties_tags.addTag(tag_noteworthy); - channel_ghi003_properties_tags.addTag(tag_noteworthy); - channel_ghi010_properties_tags.addTag(tag_noteworthy); - channel_ghi011_properties_tags.addTag(tag_noteworthy); - channel_xyz001_properties_tags.addTag(tag_noteworthy); - channel_xyz002_properties_tags.addTag(tag_noteworthy); - channel_xyz003_properties_tags.addTag(tag_noteworthy); - channel_xyz010_properties_tags.addTag(tag_noteworthy); - channel_xyz011_properties_tags.addTag(tag_noteworthy); - tag_noteworthy_channels.getChannels().add(channel_ghi001_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_ghi002_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_ghi003_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_ghi010_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_ghi011_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_xyz001_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_xyz002_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_xyz003_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_xyz010_properties_tags); - tag_noteworthy_channels.getChannels().add(channel_xyz011_properties_tags); - - ITUtilTags.assertAddTagMultipleChannels("/noteworthy", tag_noteworthy_channels); - - ITUtilTags.assertListTags(4, - tag_archived, - tag_handle_this, - tag_not_used, - tag_noteworthy); - - ITUtilTags.assertRetrieveTag("/noteworthy", tag_noteworthy_channels); - ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=true", tag_noteworthy_channels); - ITUtilTags.assertRetrieveTag("/noteworthy?withChannels=false", tag_noteworthy); - - // -------------------------------------------------------------------------------- - // NOT add tag (not_used) to any channel - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // check channels - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertListChannels(10); - - // ensure that channel is there, value not important at this stage - ITUtilChannels.assertRetrieveChannel("/ABC:DEF-XYZ:JKL:011", HttpURLConnection.HTTP_OK); - } catch (Exception e) { - fail(); - } + } + + /** Tear down test fixture, properties. */ + private static void tearDownProperties() { + try { + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- + + ITUtilProperties.assertRemoveProperty("/domain"); + ITUtilProperties.assertRemoveProperty("/element"); + ITUtilProperties.assertRemoveProperty("/type"); + ITUtilProperties.assertRemoveProperty("/cell"); + + ITUtilProperties.assertListProperties(0); + + property_domain = null; + property_element = null; + property_type = null; + property_cell = null; + + property_domain_channels = null; + property_element_channels = null; + property_type_channels = null; + property_cell_channels = null; + } catch (Exception e) { + fail(); } - - /** - * Tear down test fixture, properties. - */ - private static void tearDownProperties() { - try { - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- - - ITUtilProperties.assertRemoveProperty("/domain"); - ITUtilProperties.assertRemoveProperty("/element"); - ITUtilProperties.assertRemoveProperty("/type"); - ITUtilProperties.assertRemoveProperty("/cell"); - - ITUtilProperties.assertListProperties(0); - - property_domain = null; - property_element = null; - property_type = null; - property_cell = null; - - property_domain_channels = null; - property_element_channels = null; - property_type_channels = null; - property_cell_channels = null; - } catch (Exception e) { - fail(); - } + } + + /** Tear down test fixture, tags. */ + private static void tearDownTags() { + try { + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- + + ITUtilTags.assertRemoveTag("/archived"); + ITUtilTags.assertRemoveTag("/handle_this"); + ITUtilTags.assertRemoveTag("/noteworthy"); + ITUtilTags.assertRemoveTag("/not_used"); + + ITUtilTags.assertListTags(0); + + tag_archived = null; + tag_handle_this = null; + tag_noteworthy = null; + tag_not_used = null; + + tag_archived_channels = null; + tag_handle_this_channels = null; + tag_noteworthy_channels = null; + tag_not_used_channels = null; + } catch (Exception e) { + fail(); } - - /** - * Tear down test fixture, tags. - */ - private static void tearDownTags() { - try { - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- - - ITUtilTags.assertRemoveTag("/archived"); - ITUtilTags.assertRemoveTag("/handle_this"); - ITUtilTags.assertRemoveTag("/noteworthy"); - ITUtilTags.assertRemoveTag("/not_used"); - - ITUtilTags.assertListTags(0); - - tag_archived = null; - tag_handle_this = null; - tag_noteworthy = null; - tag_not_used = null; - - tag_archived_channels = null; - tag_handle_this_channels = null; - tag_noteworthy_channels = null; - tag_not_used_channels = null; - } catch (Exception e) { - fail(); - } + } + + /** Tear down test fixture, channels. */ + private static void tearDownChannels() { + try { + // -------------------------------------------------------------------------------- + // clean end + // -------------------------------------------------------------------------------- + + ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:001"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:002"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:003"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:010"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:011"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:001"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:002"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:003"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:010"); + ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:011"); + + ITUtilChannels.assertListChannels(0); + + channel_ghi001 = null; + channel_ghi002 = null; + channel_ghi003 = null; + channel_ghi010 = null; + channel_ghi011 = null; + channel_xyz001 = null; + channel_xyz002 = null; + channel_xyz003 = null; + channel_xyz010 = null; + channel_xyz011 = null; + + channel_ghi001_properties_tags = null; + channel_ghi002_properties_tags = null; + channel_ghi003_properties_tags = null; + channel_ghi010_properties_tags = null; + channel_ghi011_properties_tags = null; + channel_xyz001_properties_tags = null; + channel_xyz002_properties_tags = null; + channel_xyz003_properties_tags = null; + channel_xyz010_properties_tags = null; + channel_xyz011_properties_tags = null; + + channels_all_properties_tags = null; + } catch (Exception e) { + fail(); } - - /** - * Tear down test fixture, channels. - */ - private static void tearDownChannels() { - try { - // -------------------------------------------------------------------------------- - // clean end - // -------------------------------------------------------------------------------- - - ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:001"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:002"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:003"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:010"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-GHI:JKL:011"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:001"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:002"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:003"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:010"); - ITUtilChannels.assertDeleteChannel("/ABC:DEF-XYZ:JKL:011"); - - ITUtilChannels.assertListChannels(0); - - channel_ghi001 = null; - channel_ghi002 = null; - channel_ghi003 = null; - channel_ghi010 = null; - channel_ghi011 = null; - channel_xyz001 = null; - channel_xyz002 = null; - channel_xyz003 = null; - channel_xyz010 = null; - channel_xyz011 = null; - - channel_ghi001_properties_tags = null; - channel_ghi002_properties_tags = null; - channel_ghi003_properties_tags = null; - channel_ghi010_properties_tags = null; - channel_ghi011_properties_tags = null; - channel_xyz001_properties_tags = null; - channel_xyz002_properties_tags = null; - channel_xyz003_properties_tags = null; - channel_xyz010_properties_tags = null; - channel_xyz011_properties_tags = null; - - channels_all_properties_tags = null; - } catch (Exception e) { - fail(); - } - } - + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ITUtil.java b/src/test/java/org/phoebus/channelfinder/docker/ITUtil.java index f42c1b71..0245484e 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ITUtil.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ITUtil.java @@ -18,15 +18,11 @@ package org.phoebus.channelfinder.docker; -import org.springframework.http.HttpHeaders; -import org.testcontainers.containers.ComposeContainer; -import org.testcontainers.containers.ContainerState; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.DockerClient; - import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; @@ -38,313 +34,334 @@ import java.net.http.HttpResponse.BodyHandlers; import java.util.Base64; import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.springframework.http.HttpHeaders; +import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.containers.ContainerState; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils; /** - * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus on support common behavior for tests. + * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus + * on support common behavior for tests. * * @author Lars Johansson */ public class ITUtil { - // note - // port numbers can be exposed differently to avoid interference with any running instance - - private static final String AUTH_USER = "user:userPass"; - private static final String AUTH_ADMIN = "admin:adminPass"; - private static final String HEADER_JSON = "application/json"; - private static final String HEADER_BASIC = "Basic "; - - private static final String RESOURCES_CHANNELS = "/resources/channels"; - private static final String RESOURCES_PROPERTIES = "/resources/properties"; - private static final String RESOURCES_SCROLL = "/resources/scroll"; - private static final String RESOURCES_TAGS = "/resources/tags"; - - public static final String HTTP_IP_PORT_CHANNELFINDER = "http://127.0.0.1:8080/ChannelFinder"; - public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS = ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_CHANNELS; - public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES = ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_PROPERTIES; - public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_SCROLL = ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_SCROLL; - public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS = ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_TAGS; - - // integration test - docker - - private static final HttpClient CLIENT = HttpClient.newHttpClient(); - - public static final ObjectMapper MAPPER = new ObjectMapper(); - - public static final String CHANNELFINDER = "channelfinder"; - public static final String INTEGRATIONTEST_DOCKER_COMPOSE = "src/test/resources/compose.yml"; - - // code coverage - - public static final String JACOCO_EXEC_PATH = "/channelfinder/jacoco.exec"; - public static final String JACOCO_TARGET_PREFIX = "target/jacoco_"; - public static final String JACOCO_TARGET_SUFFIX = ".exec"; - public static final String JACOCO_SKIPITCOVERAGE = "skipITCoverage"; - - /** - * This class is not to be instantiated. - */ - private ITUtil() { - throw new IllegalStateException("Utility class"); - } - - /** - * Provide a default compose setup for testing. - * For Docker Compose V2. - * - * Intended usage is as field annotated with @Container from class annotated with @Testcontainers. - * - * @return compose container - */ - public static ComposeContainer defaultComposeContainers() { - return new ComposeContainer(new File(ITUtil.INTEGRATIONTEST_DOCKER_COMPOSE)) - .withEnv(ITUtil.JACOCO_SKIPITCOVERAGE, System.getProperty(ITUtil.JACOCO_SKIPITCOVERAGE)) - .withLocalCompose(true) - .waitingFor(ITUtil.CHANNELFINDER, Wait.forHealthcheck()); - } - - /** - * Extract coverage report from compose container to file system. - * - * @param environment compose container - * @param destinationPath destination path, i.e. where in file system to put coverage report - * that has been extracted from container - */ - public static void extractJacocoReport(ComposeContainer environment, String destinationPath) { - // extract jacoco report from container file system - // stop jvm to make data available - - if (!Boolean.FALSE.toString().equals(System.getProperty(ITUtil.JACOCO_SKIPITCOVERAGE))) { - return; - } - - Optional container = environment.getContainerByServiceName(ITUtil.CHANNELFINDER); - if (container.isPresent()) { - ContainerState cs = container.get(); - DockerClient dc = cs.getDockerClient(); - dc.stopContainerCmd(cs.getContainerId()).exec(); - try { - cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH, destinationPath); - } catch (Exception e) { - // proceed if file cannot be copied - } - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Assert that response object is as expected, an array with 2 elements - * of which first contains response code OK (200). - * - * @param response string array with response of http request, response code and content - * - * @see HttpURLConnection#HTTP_OK - */ - static void assertResponseLength2CodeOK(String[] response) { - assertResponseLength2Code(response, HttpURLConnection.HTTP_OK); - } - - /** - * Assert that response object is as expected, an array with 2 elements - * of which first element contains given response code. - * - * @param response string array with response of http request, response code and content - * @param expectedResponseCode expected response code - * - * @see HttpURLConnection for available response codes - */ - static void assertResponseLength2Code(String[] response, int expectedResponseCode) { - assertNotNull(response); - assertEquals(2, response.length); - assertEquals(expectedResponseCode, Integer.parseInt(response[0])); - } - - /** - * Assert that response object is as expected, an array with 2 elements - * of which first element contains response code OK (200) and second element contains given response content. - * - * @param response string array with response of http request, response code and content - * @param expectedResponseContent expected response content - * - * @see HttpURLConnection#HTTP_OK - */ - static void assertResponseLength2CodeOKContent(String[] response, String expectedResponseContent) { - assertResponseLength2CodeContent(response, HttpURLConnection.HTTP_OK, expectedResponseContent); + // note + // port numbers can be exposed differently to avoid interference with any running instance + + private static final String AUTH_USER = "user:userPass"; + private static final String AUTH_ADMIN = "admin:adminPass"; + private static final String HEADER_JSON = "application/json"; + private static final String HEADER_BASIC = "Basic "; + + private static final String RESOURCES_CHANNELS = "/resources/channels"; + private static final String RESOURCES_PROPERTIES = "/resources/properties"; + private static final String RESOURCES_SCROLL = "/resources/scroll"; + private static final String RESOURCES_TAGS = "/resources/tags"; + + public static final String HTTP_IP_PORT_CHANNELFINDER = "http://127.0.0.1:8080/ChannelFinder"; + public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS = + ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_CHANNELS; + public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES = + ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_PROPERTIES; + public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_SCROLL = + ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_SCROLL; + public static final String HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS = + ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.RESOURCES_TAGS; + + // integration test - docker + + private static final HttpClient CLIENT = HttpClient.newHttpClient(); + + public static final ObjectMapper MAPPER = new ObjectMapper(); + + public static final String CHANNELFINDER = "channelfinder"; + public static final String INTEGRATIONTEST_DOCKER_COMPOSE = "src/test/resources/compose.yml"; + + // code coverage + + public static final String JACOCO_EXEC_PATH = "/channelfinder/jacoco.exec"; + public static final String JACOCO_TARGET_PREFIX = "target/jacoco_"; + public static final String JACOCO_TARGET_SUFFIX = ".exec"; + public static final String JACOCO_SKIPITCOVERAGE = "skipITCoverage"; + + /** This class is not to be instantiated. */ + private ITUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Provide a default compose setup for testing. For Docker Compose V2. + * + *

Intended usage is as field annotated with @Container from class annotated + * with @Testcontainers. + * + * @return compose container + */ + public static ComposeContainer defaultComposeContainers() { + return new ComposeContainer(new File(ITUtil.INTEGRATIONTEST_DOCKER_COMPOSE)) + .withEnv(ITUtil.JACOCO_SKIPITCOVERAGE, System.getProperty(ITUtil.JACOCO_SKIPITCOVERAGE)) + .withLocalCompose(true) + .waitingFor(ITUtil.CHANNELFINDER, Wait.forHealthcheck()); + } + + /** + * Extract coverage report from compose container to file system. + * + * @param environment compose container + * @param destinationPath destination path, i.e. where in file system to put coverage report that + * has been extracted from container + */ + public static void extractJacocoReport(ComposeContainer environment, String destinationPath) { + // extract jacoco report from container file system + // stop jvm to make data available + + if (!Boolean.FALSE.toString().equals(System.getProperty(ITUtil.JACOCO_SKIPITCOVERAGE))) { + return; } - /** - * Assert that response object is as expected, an array with 2 elements - * of which first element contains given response code and second element contains given response content. - * - * @param response string array with response of http request, response code and content - * @param expectedResponseCode expected response code - * @param expectedResponseContent expected response content - * - * @see HttpURLConnection for available response codes - */ - static void assertResponseLength2CodeContent(String[] response, int expectedResponseCode, String expectedResponseContent) { - assertResponseLength2Code(response, expectedResponseCode); - assertEquals(expectedResponseContent, response[1]); + Optional container = + environment.getContainerByServiceName(ITUtil.CHANNELFINDER); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH, destinationPath); + } catch (Exception e) { + // proceed if file cannot be copied + } } - - // ---------------------------------------------------------------------------------------------------- - - // enum for http methods - static enum MethodChoice {POST, GET, PUT, DELETE}; - - // enum for different authorizations - static enum AuthorizationChoice {NONE, USER, ADMIN}; - - // enum for different endpoints - static enum EndpointChoice {CHANNELS, PROPERTIES, SCROLL, TAGS}; - - /** - * Utility method to build http request for test to run. - * - * @param methodChoice method choice - * @param authorizationChoice authorization choice - * @param endpointChoice endpoint choice - * @param path particular path - * @param json json data - * @return http request to run - * @throws URISyntaxException If request is created with non-legal URI characters - */ - static HttpRequest buildRequest(MethodChoice methodChoice, AuthorizationChoice authorizationChoice, EndpointChoice endpointChoice, String path, String json) throws URISyntaxException { - String pathstr = !StringUtils.isEmpty(path) - ? path - : ""; - - String str = - ITUtil.HTTP_IP_PORT_CHANNELFINDER - + ITUtil.buildUri(endpointChoice) - + pathstr; - - HttpRequest.Builder builder = HttpRequest.newBuilder() - .uri(new URI(str)) - .header(HttpHeaders.CONTENT_TYPE, HEADER_JSON); - - builder = buildAuthorization(builder, authorizationChoice); - - return buildMethodJson(builder, methodChoice, json).build(); - } - - /** - * Utility method to build http request for method and json data. - * - * @param builder http request builder - * @param methodChoice method choice, i.e. POST, GET, PUT, DELETE, PATCH - * @param json json data - * @return http request builder - */ - private static HttpRequest.Builder buildMethodJson(HttpRequest.Builder builder, MethodChoice methodChoice, String json) { - switch (methodChoice) { - case POST: - return builder.POST(HttpRequest.BodyPublishers.ofString(json)); - case GET: - return builder.GET(); - case PUT: - return builder.PUT(HttpRequest.BodyPublishers.ofString(json)); - case DELETE: - return builder.DELETE(); - default: - return builder.GET(); - } - } - - /** - * Utility method to build http client for authentication and authorization. - * Http basic authorization is used. - * - * @param builder http request builder - * @param authorizationChoice authorization choice - * @return http request builder - */ - private static HttpRequest.Builder buildAuthorization(HttpRequest.Builder builder, AuthorizationChoice authorizationChoice) { - switch (authorizationChoice) { - case ADMIN: - return builder.headers(HttpHeaders.AUTHORIZATION, HEADER_BASIC + Base64.getEncoder().encodeToString(AUTH_ADMIN.getBytes())); - case USER: - return builder.headers(HttpHeaders.AUTHORIZATION, HEADER_BASIC + Base64.getEncoder().encodeToString(AUTH_USER.getBytes())); - case NONE: - return builder; - default: - return builder; - } - } - - /** - * Utility method to build string for endpoint. To be used when constructing uri to send query to server. - * - * @param endpointChoice endpoint choice - * @return string for endpoint - */ - private static String buildUri(EndpointChoice endpointChoice) { - switch (endpointChoice) { - case CHANNELS: - return ITUtil.RESOURCES_CHANNELS; - case PROPERTIES: - return ITUtil.RESOURCES_PROPERTIES; - case SCROLL: - return ITUtil.RESOURCES_SCROLL; - case TAGS: - return ITUtil.RESOURCES_TAGS; - default: - return StringUtils.EMPTY; - } - } - - /** - * Send GET request with given string as URI and return response status code. - * - * @param str string to parse as URI - * @return response status code - * @throws URISyntaxException If request is created with non-legal URI characters - * @throws InterruptedException - * @throws IOException - */ - static int sendRequestStatusCode(String str) throws URISyntaxException, IOException, InterruptedException { - HttpRequest request = HttpRequest.newBuilder() - .uri(new URI(str)) - .GET() - .build(); - - return Integer.parseInt(sendRequest(request)[0]); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Assert that response object is as expected, an array with 2 elements of which first contains + * response code OK (200). + * + * @param response string array with response of http request, response code and content + * @see HttpURLConnection#HTTP_OK + */ + static void assertResponseLength2CodeOK(String[] response) { + assertResponseLength2Code(response, HttpURLConnection.HTTP_OK); + } + + /** + * Assert that response object is as expected, an array with 2 elements of which first element + * contains given response code. + * + * @param response string array with response of http request, response code and content + * @param expectedResponseCode expected response code + * @see HttpURLConnection for available response codes + */ + static void assertResponseLength2Code(String[] response, int expectedResponseCode) { + assertNotNull(response); + assertEquals(2, response.length); + assertEquals(expectedResponseCode, Integer.parseInt(response[0])); + } + + /** + * Assert that response object is as expected, an array with 2 elements of which first element + * contains response code OK (200) and second element contains given response content. + * + * @param response string array with response of http request, response code and content + * @param expectedResponseContent expected response content + * @see HttpURLConnection#HTTP_OK + */ + static void assertResponseLength2CodeOKContent( + String[] response, String expectedResponseContent) { + assertResponseLength2CodeContent(response, HttpURLConnection.HTTP_OK, expectedResponseContent); + } + + /** + * Assert that response object is as expected, an array with 2 elements of which first element + * contains given response code and second element contains given response content. + * + * @param response string array with response of http request, response code and content + * @param expectedResponseCode expected response code + * @param expectedResponseContent expected response content + * @see HttpURLConnection for available response codes + */ + static void assertResponseLength2CodeContent( + String[] response, int expectedResponseCode, String expectedResponseContent) { + assertResponseLength2Code(response, expectedResponseCode); + assertEquals(expectedResponseContent, response[1]); + } + + // ---------------------------------------------------------------------------------------------------- + + // enum for http methods + static enum MethodChoice { + POST, + GET, + PUT, + DELETE + }; + + // enum for different authorizations + static enum AuthorizationChoice { + NONE, + USER, + ADMIN + }; + + // enum for different endpoints + static enum EndpointChoice { + CHANNELS, + PROPERTIES, + SCROLL, + TAGS + }; + + /** + * Utility method to build http request for test to run. + * + * @param methodChoice method choice + * @param authorizationChoice authorization choice + * @param endpointChoice endpoint choice + * @param path particular path + * @param json json data + * @return http request to run + * @throws URISyntaxException If request is created with non-legal URI characters + */ + static HttpRequest buildRequest( + MethodChoice methodChoice, + AuthorizationChoice authorizationChoice, + EndpointChoice endpointChoice, + String path, + String json) + throws URISyntaxException { + String pathstr = !StringUtils.isEmpty(path) ? path : ""; + + String str = ITUtil.HTTP_IP_PORT_CHANNELFINDER + ITUtil.buildUri(endpointChoice) + pathstr; + + HttpRequest.Builder builder = + HttpRequest.newBuilder().uri(new URI(str)).header(HttpHeaders.CONTENT_TYPE, HEADER_JSON); + + builder = buildAuthorization(builder, authorizationChoice); + + return buildMethodJson(builder, methodChoice, json).build(); + } + + /** + * Utility method to build http request for method and json data. + * + * @param builder http request builder + * @param methodChoice method choice, i.e. POST, GET, PUT, DELETE, PATCH + * @param json json data + * @return http request builder + */ + private static HttpRequest.Builder buildMethodJson( + HttpRequest.Builder builder, MethodChoice methodChoice, String json) { + switch (methodChoice) { + case POST: + return builder.POST(HttpRequest.BodyPublishers.ofString(json)); + case GET: + return builder.GET(); + case PUT: + return builder.PUT(HttpRequest.BodyPublishers.ofString(json)); + case DELETE: + return builder.DELETE(); + default: + return builder.GET(); } - - /** - * Send GET request with given string as URI and return string array with response status code and response body. - * - * @param str string to parse as URI - * @return string array with response status code and response body - * @throws URISyntaxException If request is created with non-legal URI characters - * @throws InterruptedException - * @throws IOException - */ - static String[] sendRequest(String str) throws URISyntaxException, IOException, InterruptedException { - HttpRequest request = HttpRequest.newBuilder() - .uri(new URI(str)) - .GET() - .build(); - - return sendRequest(request); + } + + /** + * Utility method to build http client for authentication and authorization. Http basic + * authorization is used. + * + * @param builder http request builder + * @param authorizationChoice authorization choice + * @return http request builder + */ + private static HttpRequest.Builder buildAuthorization( + HttpRequest.Builder builder, AuthorizationChoice authorizationChoice) { + switch (authorizationChoice) { + case ADMIN: + return builder.headers( + HttpHeaders.AUTHORIZATION, + HEADER_BASIC + Base64.getEncoder().encodeToString(AUTH_ADMIN.getBytes())); + case USER: + return builder.headers( + HttpHeaders.AUTHORIZATION, + HEADER_BASIC + Base64.getEncoder().encodeToString(AUTH_USER.getBytes())); + case NONE: + return builder; + default: + return builder; } - - /** - * Send request and return response with string array with response code and response string. - * - * @param request request - * @return string array with response code and response string - * @throws InterruptedException - * @throws IOException - */ - static String[] sendRequest(HttpRequest request) throws IOException, InterruptedException { - HttpResponse response = CLIENT.send(request, BodyHandlers.ofString()); - - return new String[] {String.valueOf(response.statusCode()), response.body()}; + } + + /** + * Utility method to build string for endpoint. To be used when constructing uri to send query to + * server. + * + * @param endpointChoice endpoint choice + * @return string for endpoint + */ + private static String buildUri(EndpointChoice endpointChoice) { + switch (endpointChoice) { + case CHANNELS: + return ITUtil.RESOURCES_CHANNELS; + case PROPERTIES: + return ITUtil.RESOURCES_PROPERTIES; + case SCROLL: + return ITUtil.RESOURCES_SCROLL; + case TAGS: + return ITUtil.RESOURCES_TAGS; + default: + return StringUtils.EMPTY; } - + } + + /** + * Send GET request with given string as URI and return response status code. + * + * @param str string to parse as URI + * @return response status code + * @throws URISyntaxException If request is created with non-legal URI characters + * @throws InterruptedException + * @throws IOException + */ + static int sendRequestStatusCode(String str) + throws URISyntaxException, IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder().uri(new URI(str)).GET().build(); + + return Integer.parseInt(sendRequest(request)[0]); + } + + /** + * Send GET request with given string as URI and return string array with response status code and + * response body. + * + * @param str string to parse as URI + * @return string array with response status code and response body + * @throws URISyntaxException If request is created with non-legal URI characters + * @throws InterruptedException + * @throws IOException + */ + static String[] sendRequest(String str) + throws URISyntaxException, IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder().uri(new URI(str)).GET().build(); + + return sendRequest(request); + } + + /** + * Send request and return response with string array with response code and response string. + * + * @param request request + * @return string array with response code and response string + * @throws InterruptedException + * @throws IOException + */ + static String[] sendRequest(HttpRequest request) throws IOException, InterruptedException { + HttpResponse response = CLIENT.send(request, BodyHandlers.ofString()); + + return new String[] {String.valueOf(response.statusCode()), response.body()}; + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ITUtilChannels.java b/src/test/java/org/phoebus/channelfinder/docker/ITUtilChannels.java index 6b101480..5b8387a8 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ITUtilChannels.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ITUtilChannels.java @@ -24,455 +24,579 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import java.net.HttpURLConnection; - import com.fasterxml.jackson.core.JsonProcessingException; - -import org.phoebus.channelfinder.entity.Channel; +import java.net.HttpURLConnection; import org.phoebus.channelfinder.docker.ITUtil.AuthorizationChoice; import org.phoebus.channelfinder.docker.ITUtil.EndpointChoice; import org.phoebus.channelfinder.docker.ITUtil.MethodChoice; +import org.phoebus.channelfinder.entity.Channel; /** - * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus on support test of behavior for channel endpoints. + * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus + * on support test of behavior for channel endpoints. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.docker.ITUtil */ public class ITUtilChannels { - private static final Channel[] CHANNELS_NULL = null; - private static final Channel CHANNEL_NULL = null; - - /** - * This class is not to be instantiated. - */ - private ITUtilChannels() { - throw new IllegalStateException("Utility class"); - } - - // Note - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API ChannelManager - // -------------------- -------------------- - // Retrieve a Channel .../channels/ (GET) read(String) - // List Channels / Query by Pattern .../channels?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... - // (GET) query(MultiValueMap) - // Create / Replace Channel .../channels/ (PUT) create(String, Channel) - // Create / Replace Multiple Channels .../channels (PUT) create(Iterable) - // Update Channel .../channels/ (POST) update(String, Channel) - // Update Channels .../channels (POST) update(Iterable) - // Delete a Channel .../channels/ (DELETE) remove(String) - // ------------------------------------------------------------------------------------------------ - - /** - * Return string for channel. - * - * @param value channel - * @return string for channel - */ - static String object2Json(Channel value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; - } - /** - * Return string for channel array. - * - * @param value channel array - * @return string for channel array - */ - static String object2Json(Channel[] value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertRetrieveChannel(String, int, Channel) - */ - public static Channel assertRetrieveChannel(String path, int expectedResponseCode) { - return assertRetrieveChannel(path, expectedResponseCode, CHANNEL_NULL); - } - /** - * @see ITUtilChannels#assertRetrieveChannel(String, int, Channel) - */ - public static Channel assertRetrieveChannel(String path, Channel expected) { - return assertRetrieveChannel(path, HttpURLConnection.HTTP_OK, expected); - } - /** - * Utility method to return the full listing of a single channel with the given name. - * - * @param path path - * @param expectedResponseCode expected response code - * @param expected expected response channel - */ - public static Channel assertRetrieveChannel(String path, int expectedResponseCode, Channel expected) { - Channel actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + path); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) - */ - public static Channel[] assertListChannels(int expectedEqual) { - return assertListChannels("", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, CHANNELS_NULL); - } - /** - * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) - */ - public static Channel[] assertListChannels(int expectedEqual, Channel... expected) { - return assertListChannels("", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); - } - /** - * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) - */ - public static Channel[] assertListChannels(String queryString, Channel... expected) { - return assertListChannels(queryString, HttpURLConnection.HTTP_OK, -1, -1, expected); - } - /** - * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) - */ - public static Channel[] assertListChannels(String queryString, int expectedEqual) { - return assertListChannels(queryString, HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, CHANNELS_NULL); - } - /** - * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) - */ - public static Channel[] assertListChannels(String queryString, int expectedResponseCode, int expectedEqual) { - return assertListChannels(queryString, expectedResponseCode, expectedEqual, expectedEqual, CHANNELS_NULL); - } - /** - * Utility method to return the list of channels which match all given expressions, i.e. the expressions are combined in a logical AND. - * - * @param queryString query string - * @param expectedResponseCode response code - * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number of items - * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of items - * @param expected expected response channels - * @return number of channels - */ - public static Channel[] assertListChannels(String queryString, int expectedResponseCode, int expectedGreaterThanOrEqual, int expectedLessThanOrEqual, Channel... expected) { - Channel[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + queryString); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); - } - // expected number of items in list - // (if non-negative number) - // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual - if (expectedGreaterThanOrEqual >= 0) { - assertTrue(actual.length >= expectedGreaterThanOrEqual); - } - if (expectedLessThanOrEqual >= 0) { - assertTrue(actual.length <= expectedLessThanOrEqual); - } - if (expected != null && expected.length > 0) { - assertEqualsChannels(actual, expected); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertCountChannels(String, int, int, int) - */ - public static Integer assertCountChannels(int expectedEqual) { - return assertCountChannels("", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual); - } - /** - * @see ITUtilChannels#assertCountChannels(String, int, int, int) - */ - public static Integer assertCountChannels(String queryString, int expectedEqual) { - return assertCountChannels(queryString, HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual); - } - /** - * Utility method to return the count of channels which match all given expressions, i.e. the expressions are combined in a logical AND. - * - * @param queryString query string - * @param expectedResponseCode response code - * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number of items - * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of items - * @param expected expected response channels - * @return number of channels - */ - public static Integer assertCountChannels(String queryString, int expectedResponseCode, int expectedGreaterThanOrEqual, int expectedLessThanOrEqual) { - Integer actual = -1; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + "/count" + queryString); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = Integer.parseInt(response[1]); - } - // expected number of items in list - // (if non-negative number) - // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual - if (expectedGreaterThanOrEqual >= 0) { - assertTrue(actual >= expectedGreaterThanOrEqual); - } - if (expectedLessThanOrEqual >= 0) { - assertTrue(actual <= expectedLessThanOrEqual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertCreateReplaceChannel(String path, Channel value) { - return assertCreateReplaceChannel(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, CHANNEL_NULL); - } - /** - * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertCreateReplaceChannel(AuthorizationChoice authorizationChoice, String path, Channel value, int expectedResponseCode) { - return assertCreateReplaceChannel(authorizationChoice, path, object2Json(value), expectedResponseCode, CHANNEL_NULL); - } - /** - * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertCreateReplaceChannel(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceChannel(authorizationChoice, path, json, expectedResponseCode, CHANNEL_NULL); - } - /** - * Utility method to create or completely replace the existing channel name with the payload data. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response channel - */ - public static Channel assertCreateReplaceChannel(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Channel expected) { - Channel actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.CHANNELS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertCreateReplaceMultipleChannels(AuthorizationChoice, String, String, int, Channel[]) - */ - public static Channel[] assertCreateReplaceMultipleChannels(String path, Channel[] value) { - return assertCreateReplaceMultipleChannels(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, CHANNELS_NULL); - } - /** - * @see ITUtilChannels#assertCreateReplaceMultipleChannels(AuthorizationChoice, String, String, int, Channel[]) - */ - public static Channel[] assertCreateReplaceMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceMultipleChannels(authorizationChoice, path, json, expectedResponseCode, CHANNELS_NULL); - } - /** - * Utility method to add the channels in the payload to the directory. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response channels - */ - public static Channel[] assertCreateReplaceMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Channel[] expected) { - Channel[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.CHANNELS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); - } - - if (expected != null) { - assertEqualsChannels(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertUpdateChannel(String path, Channel value) { - return assertUpdateChannel(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, CHANNEL_NULL); - } - /** - * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertUpdateChannel(AuthorizationChoice authorizationChoice, String path, Channel value, int expectedResponseCode) { - return assertUpdateChannel(authorizationChoice, path, object2Json(value), expectedResponseCode, CHANNEL_NULL); - } - /** - * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) - */ - public static Channel assertUpdateChannel(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertUpdateChannel(authorizationChoice, path, json, expectedResponseCode, CHANNEL_NULL); - } - /** - * Utility method to merge properties and tags of the channel identified by the payload into an existing channel. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response channel - */ - public static Channel assertUpdateChannel(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Channel expected) { - Channel actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, authorizationChoice, EndpointChoice.CHANNELS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertUpdateChannels(String, String, int, Channel[]) - */ - public static Channel[] assertUpdateChannels(String path, Channel[] value) { - return assertUpdateChannels(path, object2Json(value), HttpURLConnection.HTTP_OK, CHANNELS_NULL); - } - /** - * @see ITUtilChannels#assertUpdateChannels(String, String, int, Channel[]) - */ - public static Channel[] assertUpdateChannels(String path, String json, int expectedResponseCode) { - return assertUpdateChannels(path, json, expectedResponseCode, CHANNELS_NULL); - } - /** - * Utility method to merge properties and tags of the channels identified by the payload into existing channels. - * - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response channels - */ - public static Channel[] assertUpdateChannels(String path, String json, int expectedResponseCode, Channel[] expected) { - Channel[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, AuthorizationChoice.ADMIN, EndpointChoice.CHANNELS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); - } - if (expected != null) { - assertEqualsChannels(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilChannels#assertDeleteChannel(AuthorizationChoice, String, int) - */ - public static void assertDeleteChannel(String path) { - assertDeleteChannel(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); - } - /** - * Utility method to delete the existing channel name and all its properties and tags. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param expected expected response channel - */ - public static void assertDeleteChannel(AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.DELETE, authorizationChoice, EndpointChoice.CHANNELS, path, null)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - } catch (Exception e) { - fail(); - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Assert that arrays are equal with same length and same content in each array position. - * - * @param actual actual array of Channel objects - * @param expected expected arbitray number of Channel objects - */ - static void assertEqualsChannels(Channel[] actual, Channel... expected) { - if (expected != null) { - assertNotNull(actual); - assertEquals(expected.length, actual.length); - for (int i=0; i (GET) read(String) + // List Channels / Query by Pattern + // .../channels?prop1=patt1&prop2=patt2&~tag=patt3&~name=patt4... + // (GET) + // query(MultiValueMap) + // Create / Replace Channel .../channels/ (PUT) create(String, + // Channel) + // Create / Replace Multiple Channels .../channels (PUT) + // create(Iterable) + // Update Channel .../channels/ (POST) update(String, + // Channel) + // Update Channels .../channels (POST) + // update(Iterable) + // Delete a Channel .../channels/ (DELETE) remove(String) + // + // ------------------------------------------------------------------------------------------------ + + /** + * Return string for channel. + * + * @param value channel + * @return string for channel + */ + static String object2Json(Channel value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); + } + return null; + } + + /** + * Return string for channel array. + * + * @param value channel array + * @return string for channel array + */ + static String object2Json(Channel[] value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); + } + return null; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertRetrieveChannel(String, int, Channel) + */ + public static Channel assertRetrieveChannel(String path, int expectedResponseCode) { + return assertRetrieveChannel(path, expectedResponseCode, CHANNEL_NULL); + } + + /** + * @see ITUtilChannels#assertRetrieveChannel(String, int, Channel) + */ + public static Channel assertRetrieveChannel(String path, Channel expected) { + return assertRetrieveChannel(path, HttpURLConnection.HTTP_OK, expected); + } + + /** + * Utility method to return the full listing of a single channel with the given name. + * + * @param path path + * @param expectedResponseCode expected response code + * @param expected expected response channel + */ + public static Channel assertRetrieveChannel( + String path, int expectedResponseCode, Channel expected) { + Channel actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + path); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) + */ + public static Channel[] assertListChannels(int expectedEqual) { + return assertListChannels( + "", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, CHANNELS_NULL); + } + + /** + * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) + */ + public static Channel[] assertListChannels(int expectedEqual, Channel... expected) { + return assertListChannels( + "", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); + } + + /** + * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) + */ + public static Channel[] assertListChannels(String queryString, Channel... expected) { + return assertListChannels(queryString, HttpURLConnection.HTTP_OK, -1, -1, expected); + } + + /** + * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) + */ + public static Channel[] assertListChannels(String queryString, int expectedEqual) { + return assertListChannels( + queryString, HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, CHANNELS_NULL); + } + + /** + * @see ITUtilChannels#assertListChannels(String, int, int, int, Channel...) + */ + public static Channel[] assertListChannels( + String queryString, int expectedResponseCode, int expectedEqual) { + return assertListChannels( + queryString, expectedResponseCode, expectedEqual, expectedEqual, CHANNELS_NULL); + } + + /** + * Utility method to return the list of channels which match all given expressions, i.e. the + * expressions are combined in a logical AND. + * + * @param queryString query string + * @param expectedResponseCode response code + * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number + * of items + * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of + * items + * @param expected expected response channels + * @return number of channels + */ + public static Channel[] assertListChannels( + String queryString, + int expectedResponseCode, + int expectedGreaterThanOrEqual, + int expectedLessThanOrEqual, + Channel... expected) { + Channel[] actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + queryString); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); + } + // expected number of items in list + // (if non-negative number) + // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual + if (expectedGreaterThanOrEqual >= 0) { + assertTrue(actual.length >= expectedGreaterThanOrEqual); + } + if (expectedLessThanOrEqual >= 0) { + assertTrue(actual.length <= expectedLessThanOrEqual); + } + if (expected != null && expected.length > 0) { + assertEqualsChannels(actual, expected); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertCountChannels(String, int, int, int) + */ + public static Integer assertCountChannels(int expectedEqual) { + return assertCountChannels("", HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual); + } + + /** + * @see ITUtilChannels#assertCountChannels(String, int, int, int) + */ + public static Integer assertCountChannels(String queryString, int expectedEqual) { + return assertCountChannels( + queryString, HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual); + } + + /** + * Utility method to return the count of channels which match all given expressions, i.e. the + * expressions are combined in a logical AND. + * + * @param queryString query string + * @param expectedResponseCode response code + * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number + * of items + * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of + * items + * @param expected expected response channels + * @return number of channels + */ + public static Integer assertCountChannels( + String queryString, + int expectedResponseCode, + int expectedGreaterThanOrEqual, + int expectedLessThanOrEqual) { + Integer actual = -1; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_CHANNELS + "/count" + queryString); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = Integer.parseInt(response[1]); + } + // expected number of items in list + // (if non-negative number) + // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual + if (expectedGreaterThanOrEqual >= 0) { + assertTrue(actual >= expectedGreaterThanOrEqual); + } + if (expectedLessThanOrEqual >= 0) { + assertTrue(actual <= expectedLessThanOrEqual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, + * Channel) + */ + public static Channel assertCreateReplaceChannel(String path, Channel value) { + return assertCreateReplaceChannel( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + CHANNEL_NULL); + } + + /** + * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, + * Channel) + */ + public static Channel assertCreateReplaceChannel( + AuthorizationChoice authorizationChoice, + String path, + Channel value, + int expectedResponseCode) { + return assertCreateReplaceChannel( + authorizationChoice, path, object2Json(value), expectedResponseCode, CHANNEL_NULL); + } + + /** + * @see ITUtilChannels#assertCreateReplaceChannel(AuthorizationChoice, String, String, int, + * Channel) + */ + public static Channel assertCreateReplaceChannel( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceChannel( + authorizationChoice, path, json, expectedResponseCode, CHANNEL_NULL); + } + + /** + * Utility method to create or completely replace the existing channel name with the payload data. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response channel + */ + public static Channel assertCreateReplaceChannel( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Channel expected) { + Channel actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.CHANNELS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertCreateReplaceMultipleChannels(AuthorizationChoice, String, String, + * int, Channel[]) + */ + public static Channel[] assertCreateReplaceMultipleChannels(String path, Channel[] value) { + return assertCreateReplaceMultipleChannels( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + CHANNELS_NULL); + } + + /** + * @see ITUtilChannels#assertCreateReplaceMultipleChannels(AuthorizationChoice, String, String, + * int, Channel[]) + */ + public static Channel[] assertCreateReplaceMultipleChannels( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceMultipleChannels( + authorizationChoice, path, json, expectedResponseCode, CHANNELS_NULL); + } + + /** + * Utility method to add the channels in the payload to the directory. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response channels + */ + public static Channel[] assertCreateReplaceMultipleChannels( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Channel[] expected) { + Channel[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.CHANNELS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); + } + + if (expected != null) { + assertEqualsChannels(expected, actual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) + */ + public static Channel assertUpdateChannel(String path, Channel value) { + return assertUpdateChannel( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + CHANNEL_NULL); + } + + /** + * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) + */ + public static Channel assertUpdateChannel( + AuthorizationChoice authorizationChoice, + String path, + Channel value, + int expectedResponseCode) { + return assertUpdateChannel( + authorizationChoice, path, object2Json(value), expectedResponseCode, CHANNEL_NULL); + } + + /** + * @see ITUtilChannels#assertUpdateChannel(AuthorizationChoice, String, String, int, Channel) + */ + public static Channel assertUpdateChannel( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertUpdateChannel(authorizationChoice, path, json, expectedResponseCode, CHANNEL_NULL); + } + + /** + * Utility method to merge properties and tags of the channel identified by the payload into an + * existing channel. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response channel + */ + public static Channel assertUpdateChannel( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Channel expected) { + Channel actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, authorizationChoice, EndpointChoice.CHANNELS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertUpdateChannels(String, String, int, Channel[]) + */ + public static Channel[] assertUpdateChannels(String path, Channel[] value) { + return assertUpdateChannels(path, object2Json(value), HttpURLConnection.HTTP_OK, CHANNELS_NULL); + } + + /** + * @see ITUtilChannels#assertUpdateChannels(String, String, int, Channel[]) + */ + public static Channel[] assertUpdateChannels(String path, String json, int expectedResponseCode) { + return assertUpdateChannels(path, json, expectedResponseCode, CHANNELS_NULL); + } + + /** + * Utility method to merge properties and tags of the channels identified by the payload into + * existing channels. + * + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response channels + */ + public static Channel[] assertUpdateChannels( + String path, String json, int expectedResponseCode, Channel[] expected) { + Channel[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, + AuthorizationChoice.ADMIN, + EndpointChoice.CHANNELS, + path, + json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Channel[].class); + } + if (expected != null) { + assertEqualsChannels(expected, actual); + } + } catch (Exception e) { + fail(); + } + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilChannels#assertDeleteChannel(AuthorizationChoice, String, int) + */ + public static void assertDeleteChannel(String path) { + assertDeleteChannel(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); + } + + /** + * Utility method to delete the existing channel name and all its properties and tags. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param expected expected response channel + */ + public static void assertDeleteChannel( + AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.DELETE, authorizationChoice, EndpointChoice.CHANNELS, path, null)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + } catch (Exception e) { + fail(); + } + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Assert that arrays are equal with same length and same content in each array position. + * + * @param actual actual array of Channel objects + * @param expected expected arbitray number of Channel objects + */ + static void assertEqualsChannels(Channel[] actual, Channel... expected) { + if (expected != null) { + assertNotNull(actual); + assertEquals(expected.length, actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } + } else { + assertNull(actual); + } + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ITUtilProperties.java b/src/test/java/org/phoebus/channelfinder/docker/ITUtilProperties.java index 4899fb40..b2f509d0 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ITUtilProperties.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ITUtilProperties.java @@ -24,439 +24,573 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import java.net.HttpURLConnection; - import com.fasterxml.jackson.core.JsonProcessingException; - -import org.phoebus.channelfinder.entity.Property; +import java.net.HttpURLConnection; import org.phoebus.channelfinder.docker.ITUtil.AuthorizationChoice; import org.phoebus.channelfinder.docker.ITUtil.EndpointChoice; import org.phoebus.channelfinder.docker.ITUtil.MethodChoice; +import org.phoebus.channelfinder.entity.Property; /** - * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus on support test of behavior for property endpoints. + * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus + * on support test of behavior for property endpoints. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.docker.ITUtil */ public class ITUtilProperties { - private static final Property[] PROPERTIES_NULL = null; - private static final Property PROPERTY_NULL = null; - - /** - * This class is not to be instantiated. - */ - private ITUtilProperties() { - throw new IllegalStateException("Utility class"); + private static final Property[] PROPERTIES_NULL = null; + private static final Property PROPERTY_NULL = null; + + /** This class is not to be instantiated. */ + private ITUtilProperties() { + throw new IllegalStateException("Utility class"); + } + + // Note + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + // CHANNELFINDER API + // PropertyManager + // -------------------- + // -------------------- + // Retrieve a Property .../properties/ + // (GET) read(String, boolean) + // List Properties .../properties + // (GET) list() + // Create/Replace a Property .../properties/ + // (PUT) create(String, Property) + // Add Property to a Single Channel .../properties// + // (PUT) addSingle(String, String, Property) + // Create/Replace Properties .../properties + // (PUT) create(Iterable) + // Add Property to Multiple Channels .../properties/ + // (POST) update(String, Property) + // Add Multiple Properties .../properties + // (POST) update(Iterable) + // Remove Property from Single Channel .../properties// + // (DELETE) removeSingle(String, String) + // Remove Property .../properties/ + // (DELETE) remove(String) + // + // ------------------------------------------------------------------------------------------------ + + /** + * Return string for property. + * + * @param value property + * @return string for property + */ + static String object2Json(Property value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); } - - // Note - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API PropertyManager - // -------------------- -------------------- - // Retrieve a Property .../properties/ (GET) read(String, boolean) - // List Properties .../properties (GET) list() - // Create/Replace a Property .../properties/ (PUT) create(String, Property) - // Add Property to a Single Channel .../properties// (PUT) addSingle(String, String, Property) - // Create/Replace Properties .../properties (PUT) create(Iterable) - // Add Property to Multiple Channels .../properties/ (POST) update(String, Property) - // Add Multiple Properties .../properties (POST) update(Iterable) - // Remove Property from Single Channel .../properties// (DELETE) removeSingle(String, String) - // Remove Property .../properties/ (DELETE) remove(String) - // ------------------------------------------------------------------------------------------------ - - /** - * Return string for property. - * - * @param value property - * @return string for property - */ - static String object2Json(Property value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; + return null; + } + + /** + * Return string for property array. + * + * @param value property array + * @return string for property array + */ + static String object2Json(Property[] value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); } - /** - * Return string for property array. - * - * @param value property array - * @return string for property array - */ - static String object2Json(Property[] value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; + return null; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertRetrieveProperty(String, int, Property) + */ + public static Property assertRetrieveProperty(String path, int expectedResponseCode) { + return assertRetrieveProperty(path, expectedResponseCode, PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertRetrieveProperty(String, int, Property) + */ + public static Property assertRetrieveProperty(String path, Property expected) { + return assertRetrieveProperty(path, HttpURLConnection.HTTP_OK, expected); + } + + /** + * Utility method to return the property with the given name, listing all channels with that + * property in an embedded structure. + * + * @param path path + * @param expectedResponseCode expected response code + * @param expected expected response property + */ + public static Property assertRetrieveProperty( + String path, int expectedResponseCode, Property expected) { + Property actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES + path); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertRetrieveProperty(String, int, Property) - */ - public static Property assertRetrieveProperty(String path, int expectedResponseCode) { - return assertRetrieveProperty(path, expectedResponseCode, PROPERTY_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertListProperties(int, int, int, Property...) + */ + public static Property[] assertListProperties(int expectedEqual, Property... expected) { + return assertListProperties(HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); + } + + /** + * Utility method to return the list of all properties in the directory. + * + * @param expectedResponseCode expected response code + * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number + * of items + * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of + * items + * @param expected expected response properties + * @return number of properties + */ + public static Property[] assertListProperties( + int expectedResponseCode, + int expectedGreaterThanOrEqual, + int expectedLessThanOrEqual, + Property... expected) { + Property[] actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property[].class); + } + // expected number of items in list + // (if non-negative number) + // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual + if (expectedGreaterThanOrEqual >= 0) { + assertTrue(actual.length >= expectedGreaterThanOrEqual); + } + if (expectedLessThanOrEqual >= 0) { + assertTrue(actual.length <= expectedLessThanOrEqual); + } + if (expected != null && expected.length > 0) { + assertEqualsXmlProperties(actual, expected); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilProperties#assertRetrieveProperty(String, int, Property) - */ - public static Property assertRetrieveProperty(String path, Property expected) { - return assertRetrieveProperty(path, HttpURLConnection.HTTP_OK, expected); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, + * Property) + */ + public static Property assertCreateReplaceProperty(String path, Property value) { + return assertCreateReplaceProperty( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, + * Property) + */ + public static Property assertCreateReplaceProperty( + AuthorizationChoice authorizationChoice, String path, Property value) { + return assertCreateReplaceProperty( + authorizationChoice, path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, + * Property) + */ + public static Property assertCreateReplaceProperty( + AuthorizationChoice authorizationChoice, + String path, + Property value, + int expectedResponseCode) { + return assertCreateReplaceProperty( + authorizationChoice, path, object2Json(value), expectedResponseCode, PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, + * Property) + */ + public static Property assertCreateReplaceProperty( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceProperty( + authorizationChoice, path, json, expectedResponseCode, PROPERTY_NULL); + } + + /** + * Utility method to create or completely replace the existing property name with the payload + * data. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response property + */ + public static Property assertCreateReplaceProperty( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Property expected) { + Property actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * Utility method to return the property with the given name, listing all channels with that property in an embedded structure. - * - * @param path path - * @param expectedResponseCode expected response code - * @param expected expected response property - */ - public static Property assertRetrieveProperty(String path, int expectedResponseCode, Property expected) { - Property actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES + path); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertAddPropertySingleChannel(String, Property, Property) + */ + public static Property assertAddPropertySingleChannel(String path, Property value) { + return assertAddPropertySingleChannel(path, value, HttpURLConnection.HTTP_OK, PROPERTY_NULL); + } + + /** + * Utility method to add property with the given property_name to the channel with the given + * channel_name. + * + * @param path path + * @param value property + * @param expectedResponseCode expected response code + * @param expected expected response property + */ + public static Property assertAddPropertySingleChannel( + String path, Property value, int expectedResponseCode, Property expected) { + Property actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, + AuthorizationChoice.ADMIN, + EndpointChoice.PROPERTIES, + path, + ITUtil.MAPPER.writeValueAsString(value))); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertListProperties(int, int, int, Property...) - */ - public static Property[] assertListProperties(int expectedEqual, Property... expected) { - return assertListProperties(HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); - } - /** - * Utility method to return the list of all properties in the directory. - * - * @param expectedResponseCode expected response code - * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number of items - * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of items - * @param expected expected response properties - * @return number of properties - */ - public static Property[] assertListProperties(int expectedResponseCode, int expectedGreaterThanOrEqual, int expectedLessThanOrEqual, Property... expected) { - Property[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_PROPERTIES); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property[].class); - } - // expected number of items in list - // (if non-negative number) - // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual - if (expectedGreaterThanOrEqual >= 0) { - assertTrue(actual.length >= expectedGreaterThanOrEqual); - } - if (expectedLessThanOrEqual >= 0) { - assertTrue(actual.length <= expectedLessThanOrEqual); - } - if (expected != null && expected.length > 0) { - assertEqualsXmlProperties(actual, expected); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertCreateReplaceProperty(String path, Property value) { - return assertCreateReplaceProperty(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTY_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertCreateReplaceProperties(AuthorizationChoice, String, String, int, + * Property[]) + */ + public static Property[] assertCreateReplaceProperties(String path, Property[] value) { + return assertCreateReplaceProperties( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + PROPERTIES_NULL); + } + + /** + * @see ITUtilProperties#assertCreateReplaceProperties(AuthorizationChoice, String, String, int, + * Property[]) + */ + public static Property[] assertCreateReplaceProperties( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceProperties( + authorizationChoice, path, json, expectedResponseCode, PROPERTIES_NULL); + } + + /** + * Utility method to add the properties in the payload to the directory. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response properties + */ + public static Property[] assertCreateReplaceProperties( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Property[] expected) { + Property[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property[].class); + } + if (expected != null) { + assertEqualsXmlProperties(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertCreateReplaceProperty(AuthorizationChoice authorizationChoice, String path, Property value) { - return assertCreateReplaceProperty(authorizationChoice, path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTY_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, + * int, Property) + */ + public static Property assertAddPropertyMultipleChannels(String path, Property value) { + return assertAddPropertyMultipleChannels( + AuthorizationChoice.ADMIN, + path, + object2Json(value), + HttpURLConnection.HTTP_OK, + PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, + * int, Property) + */ + public static Property assertAddPropertyMultipleChannels( + AuthorizationChoice authorizationChoice, + String path, + Property value, + int expectedResponseCode) { + return assertAddPropertyMultipleChannels( + authorizationChoice, path, object2Json(value), expectedResponseCode, PROPERTY_NULL); + } + + /** + * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, + * int, Property) + */ + public static Property assertAddPropertyMultipleChannels( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertAddPropertyMultipleChannels( + authorizationChoice, path, json, expectedResponseCode, PROPERTY_NULL); + } + + /** + * Utility method to add property with the given name to all channels in the payload data. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response property + */ + public static Property assertAddPropertyMultipleChannels( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Property expected) { + Property actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertCreateReplaceProperty(AuthorizationChoice authorizationChoice, String path, Property value, int expectedResponseCode) { - return assertCreateReplaceProperty(authorizationChoice, path, object2Json(value), expectedResponseCode, PROPERTY_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertAddMultipleProperties(String, String, int, Property[]) + */ + public static Property[] assertAddMultipleProperties(String path, Property[] value) { + return assertAddMultipleProperties( + path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTIES_NULL); + } + + /** + * @see ITUtilProperties#assertAddMultipleProperties(String, String, int, Property[]) + */ + public static Property[] assertAddMultipleProperties( + String path, String json, int expectedResponseCode) { + return assertAddMultipleProperties(path, json, expectedResponseCode, PROPERTIES_NULL); + } + + /** + * Utility method to add properties in the payload to all channels in the payload data. + * + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response properties + */ + public static Property[] assertAddMultipleProperties( + String path, String json, int expectedResponseCode, Property[] expected) { + Property[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, + AuthorizationChoice.ADMIN, + EndpointChoice.PROPERTIES, + path, + json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Property[].class); + } + if (expected != null) { + assertEqualsXmlProperties(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilProperties#assertCreateReplaceProperty(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertCreateReplaceProperty(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceProperty(authorizationChoice, path, json, expectedResponseCode, PROPERTY_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Utility method to remove property with the given property_name from the channel with the given + * channel_name. + * + * @param path path + */ + public static void assertRemovePropertySingleChannel(String path) { + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.DELETE, + AuthorizationChoice.ADMIN, + EndpointChoice.PROPERTIES, + path, + null)); + + ITUtil.assertResponseLength2CodeOK(response); + } catch (Exception e) { + fail(); } - /** - * Utility method to create or completely replace the existing property name with the payload data. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response property - */ - public static Property assertCreateReplaceProperty(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Property expected) { - Property actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilProperties#assertRemoveProperty(AuthorizationChoice, String, int) + */ + public static void assertRemoveProperty(String path) { + assertRemoveProperty(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); + } + + /** + * Utility method to remove property with the given name from all channels. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param expectedResponseCode expected response code + */ + public static void assertRemoveProperty( + AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.DELETE, authorizationChoice, EndpointChoice.PROPERTIES, path, null)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertAddPropertySingleChannel(String, Property, Property) - */ - public static Property assertAddPropertySingleChannel(String path, Property value) { - return assertAddPropertySingleChannel(path, value, HttpURLConnection.HTTP_OK, PROPERTY_NULL); - } - /** - * Utility method to add property with the given property_name to the channel with the given channel_name. - * - * @param path path - * @param value property - * @param expectedResponseCode expected response code - * @param expected expected response property - */ - public static Property assertAddPropertySingleChannel(String path, Property value, int expectedResponseCode, Property expected) { - Property actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, AuthorizationChoice.ADMIN, EndpointChoice.PROPERTIES, path, ITUtil.MAPPER.writeValueAsString(value))); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertCreateReplaceProperties(AuthorizationChoice, String, String, int, Property[]) - */ - public static Property[] assertCreateReplaceProperties(String path, Property[] value) { - return assertCreateReplaceProperties(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTIES_NULL); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Assert that arrays are equal with same length and same content in each array position. + * + * @param actual actual array of Property objects + * @param expected expected arbitrary number of Property objects + */ + static void assertEqualsXmlProperties(Property[] actual, Property... expected) { + if (expected != null) { + assertNotNull(actual); + assertEquals(expected.length, actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } + } else { + assertNull(actual); } - /** - * @see ITUtilProperties#assertCreateReplaceProperties(AuthorizationChoice, String, String, int, Property[]) - */ - public static Property[] assertCreateReplaceProperties(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceProperties(authorizationChoice, path, json, expectedResponseCode, PROPERTIES_NULL); - } - /** - * Utility method to add the properties in the payload to the directory. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response properties - */ - public static Property[] assertCreateReplaceProperties(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Property[] expected) { - Property[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property[].class); - } - if (expected != null) { - assertEqualsXmlProperties(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertAddPropertyMultipleChannels(String path, Property value) { - return assertAddPropertyMultipleChannels(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTY_NULL); - } - /** - * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertAddPropertyMultipleChannels(AuthorizationChoice authorizationChoice, String path, Property value, int expectedResponseCode) { - return assertAddPropertyMultipleChannels(authorizationChoice, path, object2Json(value), expectedResponseCode, PROPERTY_NULL); - } - /** - * @see ITUtilProperties#assertAddPropertyMultipleChannels(AuthorizationChoice, String, String, int, Property) - */ - public static Property assertAddPropertyMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertAddPropertyMultipleChannels(authorizationChoice, path, json, expectedResponseCode, PROPERTY_NULL); - } - /** - * Utility method to add property with the given name to all channels in the payload data. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response property - */ - public static Property assertAddPropertyMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Property expected) { - Property actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, authorizationChoice, EndpointChoice.PROPERTIES, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertAddMultipleProperties(String, String, int, Property[]) - */ - public static Property[] assertAddMultipleProperties(String path, Property[] value) { - return assertAddMultipleProperties(path, object2Json(value), HttpURLConnection.HTTP_OK, PROPERTIES_NULL); - } - /** - * @see ITUtilProperties#assertAddMultipleProperties(String, String, int, Property[]) - */ - public static Property[] assertAddMultipleProperties(String path, String json, int expectedResponseCode) { - return assertAddMultipleProperties(path, json, expectedResponseCode, PROPERTIES_NULL); - } - /** - * Utility method to add properties in the payload to all channels in the payload data. - * - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response properties - */ - public static Property[] assertAddMultipleProperties(String path, String json, int expectedResponseCode, Property[] expected) { - Property[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, AuthorizationChoice.ADMIN, EndpointChoice.PROPERTIES, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Property[].class); - } - if (expected != null) { - assertEqualsXmlProperties(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Utility method to remove property with the given property_name from the channel with the given channel_name. - * - * @param path path - */ - public static void assertRemovePropertySingleChannel(String path) { - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.DELETE, AuthorizationChoice.ADMIN, EndpointChoice.PROPERTIES, path, null)); - - ITUtil.assertResponseLength2CodeOK(response); - } catch (Exception e) { - fail(); - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilProperties#assertRemoveProperty(AuthorizationChoice, String, int) - */ - public static void assertRemoveProperty(String path) { - assertRemoveProperty(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); - } - /** - * Utility method to remove property with the given name from all channels. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param expectedResponseCode expected response code - */ - public static void assertRemoveProperty(AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.DELETE, authorizationChoice, EndpointChoice.PROPERTIES, path, null)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - } catch (Exception e) { - fail(); - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Assert that arrays are equal with same length and same content in each array position. - * - * @param actual actual array of Property objects - * @param expected expected arbitrary number of Property objects - */ - static void assertEqualsXmlProperties(Property[] actual, Property... expected) { - if (expected != null) { - assertNotNull(actual); - assertEquals(expected.length, actual.length); - for (int i=0; i= 0) { - assertEquals(expectedLength, actual.getChannels().size()); - } - } catch (Exception e) { - fail(); - } - return actual; - } + /** + * @see ITUtilScroll#assertQueryChannels(String, int, String, int) + */ + public static Scroll assertQueryChannels( + String queryString, int expectedResponseCode, int expectedLength) { + return assertQueryChannels(queryString, expectedResponseCode, null, expectedLength); + } - // ---------------------------------------------------------------------------------------------------- + /** + * Utility method to return scroll object, including scroll id for the next query and a list of + * the first 100(current default size) channels. + * + * @param queryString query string + * @param expectedResponseCode expected response code + * @param expectedId (if non-null) expected id + * @param expectedLength (if non-negative number) expected length of channels + * @return scroll object + */ + public static Scroll assertQueryChannels( + String queryString, int expectedResponseCode, String expectedId, int expectedLength) { + Scroll actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_SCROLL + queryString); - /** - * @see ITUtilScroll#assertContinueChannelsQuery(String, int, String, int) - */ - public static Scroll assertContinueChannelsQuery(String path, int expectedLength) { - return assertContinueChannelsQuery(path, HttpURLConnection.HTTP_OK, null, expectedLength); + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (expectedResponseCode == HttpURLConnection.HTTP_OK) { + actual = ITUtil.MAPPER.readValue(response[1], Scroll.class); + } + if (expectedId != null) { + assertEquals(expectedId, actual.getId()); + } + // (if non-negative number) expected length of channels + if (expectedLength >= 0) { + assertEquals(expectedLength, actual.getChannels().size()); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilScroll#assertContinueChannelsQuery(String, int, String, int) - */ - public static Scroll assertContinueChannelsQuery(String path, int expectedResponseCode, int expectedLength) { - return assertContinueChannelsQuery(path, expectedResponseCode, null, expectedLength); - } - /** - * Utility method to return scroll object, including scroll id for the next query and a list of the next 100(current default size) channels. - * - * @param path path - * @param expectedResponseCode expected response code - * @param expectedId (if non-null) expected id - * @param expectedLength (if non-negative number) expected length of channels - * @return scroll object - */ - public static Scroll assertContinueChannelsQuery(String path, int expectedResponseCode, String expectedId, int expectedLength) { - Scroll actual = null; - try { - String[] response = null; + return actual; + } - response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_SCROLL + path); - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (expectedResponseCode == HttpURLConnection.HTTP_OK) { - actual = ITUtil.MAPPER.readValue(response[1], Scroll.class); - } - if (expectedId != null) { - assertEquals(expectedId, actual.getId()); - } - // (if non-negative number) expected length of channels - if (expectedLength >= 0) { - assertEquals(expectedLength, actual.getChannels().size()); - } - } catch (Exception e) { - fail(); - } - return actual; - } + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilScroll#assertContinueChannelsQuery(String, int, String, int) + */ + public static Scroll assertContinueChannelsQuery(String path, int expectedLength) { + return assertContinueChannelsQuery(path, HttpURLConnection.HTTP_OK, null, expectedLength); + } + /** + * @see ITUtilScroll#assertContinueChannelsQuery(String, int, String, int) + */ + public static Scroll assertContinueChannelsQuery( + String path, int expectedResponseCode, int expectedLength) { + return assertContinueChannelsQuery(path, expectedResponseCode, null, expectedLength); + } + + /** + * Utility method to return scroll object, including scroll id for the next query and a list of + * the next 100(current default size) channels. + * + * @param path path + * @param expectedResponseCode expected response code + * @param expectedId (if non-null) expected id + * @param expectedLength (if non-negative number) expected length of channels + * @return scroll object + */ + public static Scroll assertContinueChannelsQuery( + String path, int expectedResponseCode, String expectedId, int expectedLength) { + Scroll actual = null; + try { + String[] response = null; + + response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_SCROLL + path); + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (expectedResponseCode == HttpURLConnection.HTTP_OK) { + actual = ITUtil.MAPPER.readValue(response[1], Scroll.class); + } + if (expectedId != null) { + assertEquals(expectedId, actual.getId()); + } + // (if non-negative number) expected length of channels + if (expectedLength >= 0) { + assertEquals(expectedLength, actual.getChannels().size()); + } + } catch (Exception e) { + fail(); + } + return actual; + } } diff --git a/src/test/java/org/phoebus/channelfinder/docker/ITUtilTags.java b/src/test/java/org/phoebus/channelfinder/docker/ITUtilTags.java index a119e42b..64fa5e83 100644 --- a/src/test/java/org/phoebus/channelfinder/docker/ITUtilTags.java +++ b/src/test/java/org/phoebus/channelfinder/docker/ITUtilTags.java @@ -24,439 +24,529 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import java.net.HttpURLConnection; - import com.fasterxml.jackson.core.JsonProcessingException; - -import org.phoebus.channelfinder.entity.Tag; +import java.net.HttpURLConnection; import org.phoebus.channelfinder.docker.ITUtil.AuthorizationChoice; import org.phoebus.channelfinder.docker.ITUtil.EndpointChoice; import org.phoebus.channelfinder.docker.ITUtil.MethodChoice; +import org.phoebus.channelfinder.entity.Tag; /** - * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus on support test of behavior for tag endpoints. + * Utility class to help (Docker) integration tests for ChannelFinder and Elasticsearch with focus + * on support test of behavior for tag endpoints. * * @author Lars Johansson - * * @see org.phoebus.channelfinder.docker.ITUtil */ public class ITUtilTags { - private static final Tag[] TAGS_NULL = null; - private static final Tag TAG_NULL = null; - - /** - * This class is not to be instantiated. - */ - private ITUtilTags() { - throw new IllegalStateException("Utility class"); + private static final Tag[] TAGS_NULL = null; + private static final Tag TAG_NULL = null; + + /** This class is not to be instantiated. */ + private ITUtilTags() { + throw new IllegalStateException("Utility class"); + } + + // Note + // + // ------------------------------------------------------------------------------------------------ + // ChannelFinder - Enhanced Directory Service + // https://channelfinder.readthedocs.io/en/latest/api.html + // + // ------------------------------------------------------------------------------------------------ + // CHANNELFINDER API TagManager + // -------------------- + // -------------------- + // Retrieve a Tag .../tags/ (GET) + // read(String, boolean) + // List Tags .../tags (GET) list() + // Create/Replace a Tag .../tags/ (PUT) + // create(String, Tag) + // Add Tag to a Single Channel .../tags// (PUT) + // addSingle(String, String, Tag) + // Create/Replace Tags .../tags/ (PUT) + // create(Iterable) + // Add Tag to Multiple Channels .../tags/ (POST) + // update(String, Tag) + // Add Multiple Tags .../tags (POST) + // update(Iterable) + // Remove Tag from Single Channel .../tags// (DELETE) + // removeSingle(String, String) + // Remove Tag .../tags/ (DELETE) + // remove(String) + // + // ------------------------------------------------------------------------------------------------ + + /** + * Return string for tag. + * + * @param value tag + * @return string for tag + */ + static String object2Json(Tag value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); } - - // Note - // ------------------------------------------------------------------------------------------------ - // ChannelFinder - Enhanced Directory Service - // https://channelfinder.readthedocs.io/en/latest/api.html - // ------------------------------------------------------------------------------------------------ - // CHANNELFINDER API TagManager - // -------------------- -------------------- - // Retrieve a Tag .../tags/ (GET) read(String, boolean) - // List Tags .../tags (GET) list() - // Create/Replace a Tag .../tags/ (PUT) create(String, Tag) - // Add Tag to a Single Channel .../tags// (PUT) addSingle(String, String, Tag) - // Create/Replace Tags .../tags/ (PUT) create(Iterable) - // Add Tag to Multiple Channels .../tags/ (POST) update(String, Tag) - // Add Multiple Tags .../tags (POST) update(Iterable) - // Remove Tag from Single Channel .../tags// (DELETE) removeSingle(String, String) - // Remove Tag .../tags/ (DELETE) remove(String) - // ------------------------------------------------------------------------------------------------ - - /** - * Return string for tag. - * - * @param value tag - * @return string for tag - */ - static String object2Json(Tag value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; + return null; + } + + /** + * Return string for tag array. + * + * @param value tag array + * @return string for tag array + */ + static String object2Json(Tag[] value) { + try { + return ITUtil.MAPPER.writeValueAsString(value); + } catch (JsonProcessingException e) { + fail(); } - /** - * Return string for tag array. - * - * @param value tag array - * @return string for tag array - */ - static String object2Json(Tag[] value) { - try { - return ITUtil.MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { - fail(); - } - return null; + return null; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertRetrieveTag(String, int, Tag) + */ + public static Tag assertRetrieveTag(String path, int expectedResponseCode) { + return assertRetrieveTag(path, expectedResponseCode, TAG_NULL); + } + + /** + * @see ITUtilTags#assertRetrieveTag(String, int, Tag) + */ + public static Tag assertRetrieveTag(String path, Tag expected) { + return assertRetrieveTag(path, HttpURLConnection.HTTP_OK, expected); + } + + /** + * Utility method to return the tag with the given name, listing all tagged channels in an + * embedded structure. + * + * @param path path + * @param expectedResponseCode expected response code + * @param expected expected response tag + */ + public static Tag assertRetrieveTag(String path, int expectedResponseCode, Tag expected) { + Tag actual = null; + try { + String[] response = + ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS + path); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertRetrieveTag(String, int, Tag) - */ - public static Tag assertRetrieveTag(String path, int expectedResponseCode) { - return assertRetrieveTag(path, expectedResponseCode, TAG_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertListTags(int, int, int, Tag...) + */ + public static Tag[] assertListTags(int expectedEqual, Tag... expected) { + return assertListTags(HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); + } + + /** + * Utility method to return the list of all tags in the directory. + * + * @param expectedResponseCode expected response code + * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number + * of items + * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of + * items + * @param expected expected response tags + * @return number of tags + */ + public static Tag[] assertListTags( + int expectedResponseCode, + int expectedGreaterThanOrEqual, + int expectedLessThanOrEqual, + Tag... expected) { + Tag[] actual = null; + try { + String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); + } + // expected number of items in list + // (if non-negative number) + // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual + if (expectedGreaterThanOrEqual >= 0) { + assertTrue(actual.length >= expectedGreaterThanOrEqual); + } + if (expectedLessThanOrEqual >= 0) { + assertTrue(actual.length <= expectedLessThanOrEqual); + } + if (expected != null && expected.length > 0) { + assertEqualsTags(actual, expected); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilTags#assertRetrieveTag(String, int, Tag) - */ - public static Tag assertRetrieveTag(String path, Tag expected) { - return assertRetrieveTag(path, HttpURLConnection.HTTP_OK, expected); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertCreateReplaceTag(String path, Tag value) { + return assertCreateReplaceTag( + AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); + } + + /** + * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertCreateReplaceTag( + AuthorizationChoice authorizationChoice, String path, Tag value) { + return assertCreateReplaceTag( + authorizationChoice, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); + } + + /** + * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertCreateReplaceTag( + AuthorizationChoice authorizationChoice, String path, Tag value, int expectedResponseCode) { + return assertCreateReplaceTag( + authorizationChoice, path, object2Json(value), expectedResponseCode, TAG_NULL); + } + + /** + * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertCreateReplaceTag( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceTag(authorizationChoice, path, json, expectedResponseCode, TAG_NULL); + } + + /** + * Utility method to create or completely replace the existing tag name with the payload data. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response tag + */ + public static Tag assertCreateReplaceTag( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Tag expected) { + Tag actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.TAGS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * Utility method to return the tag with the given name, listing all tagged channels in an embedded structure. - * - * @param path path - * @param expectedResponseCode expected response code - * @param expected expected response tag - */ - public static Tag assertRetrieveTag(String path, int expectedResponseCode, Tag expected) { - Tag actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS + path); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertAddTagSingleChannel(String, Tag, Tag) + */ + public static Tag assertAddTagSingleChannel(String path, Tag value) { + return assertAddTagSingleChannel(path, value, HttpURLConnection.HTTP_OK, TAG_NULL); + } + + /** + * Utility method to add tag with the given tag_name to the channel with the given channel_name. + * + * @param path path + * @param value tag + * @param expectedResponseCode expected response code + * @param expected expected response tag + */ + public static Tag assertAddTagSingleChannel( + String path, Tag value, int expectedResponseCode, Tag expected) { + Tag actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, + AuthorizationChoice.ADMIN, + EndpointChoice.TAGS, + path, + ITUtil.MAPPER.writeValueAsString(value))); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertListTags(int, int, int, Tag...) - */ - public static Tag[] assertListTags(int expectedEqual, Tag... expected) { - return assertListTags(HttpURLConnection.HTTP_OK, expectedEqual, expectedEqual, expected); - } - /** - * Utility method to return the list of all tags in the directory. - * - * @param expectedResponseCode expected response code - * @param expectedGreaterThanOrEqual (if non-negative number) greater than or equal to this number of items - * @param expectedLessThanOrEqual (if non-negative number) less than or equal to this number of items - * @param expected expected response tags - * @return number of tags - */ - public static Tag[] assertListTags(int expectedResponseCode, int expectedGreaterThanOrEqual, int expectedLessThanOrEqual, Tag... expected) { - Tag[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.HTTP_IP_PORT_CHANNELFINDER_RESOURCES_TAGS); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); - } - // expected number of items in list - // (if non-negative number) - // expectedGreaterThanOrEqual <= nbr of items <= expectedLessThanOrEqual - if (expectedGreaterThanOrEqual >= 0) { - assertTrue(actual.length >= expectedGreaterThanOrEqual); - } - if (expectedLessThanOrEqual >= 0) { - assertTrue(actual.length <= expectedLessThanOrEqual); - } - if (expected != null && expected.length > 0) { - assertEqualsTags(actual, expected); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertCreateReplaceTag(String path, Tag value) { - return assertCreateReplaceTag(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertCreateReplaceTags(AuthorizationChoice, String, String, int, Tag[]) + */ + public static Tag[] assertCreateReplaceTags(String path, Tag[] value) { + return assertCreateReplaceTags( + AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAGS_NULL); + } + + /** + * @see ITUtilTags#assertCreateReplaceTags(AuthorizationChoice, String, String, int, Tag[]) + */ + public static Tag[] assertCreateReplaceTags( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertCreateReplaceTags( + authorizationChoice, path, json, expectedResponseCode, TAGS_NULL); + } + + /** + * Utility method to add the tags in the payload to the directory. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response tags + */ + public static Tag[] assertCreateReplaceTags( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Tag[] expected) { + Tag[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.PUT, authorizationChoice, EndpointChoice.TAGS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); + } + if (expected != null) { + assertEqualsTags(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertCreateReplaceTag(AuthorizationChoice authorizationChoice, String path, Tag value) { - return assertCreateReplaceTag(authorizationChoice, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertAddTagMultipleChannels(String path, Tag value) { + return assertAddTagMultipleChannels( + AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); + } + + /** + * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertAddTagMultipleChannels( + AuthorizationChoice authorizationChoice, String path, Tag value, int expectedResponseCode) { + return assertAddTagMultipleChannels( + authorizationChoice, path, object2Json(value), expectedResponseCode, TAG_NULL); + } + + /** + * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) + */ + public static Tag assertAddTagMultipleChannels( + AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { + return assertAddTagMultipleChannels( + authorizationChoice, path, json, expectedResponseCode, TAG_NULL); + } + + /** + * Utility method to add tag with the given name to all channels in the payload data. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param json json + * @param expectedResponseCode expected response code + * @param expected expected response tag + */ + public static Tag assertAddTagMultipleChannels( + AuthorizationChoice authorizationChoice, + String path, + String json, + int expectedResponseCode, + Tag expected) { + Tag actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, authorizationChoice, EndpointChoice.TAGS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag.class); + } + if (expected != null) { + assertEquals(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertCreateReplaceTag(AuthorizationChoice authorizationChoice, String path, Tag value, int expectedResponseCode) { - return assertCreateReplaceTag(authorizationChoice, path, object2Json(value), expectedResponseCode, TAG_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertAddMultipleTags(String, String, int, Tag[]) + */ + public static Tag[] assertAddMultipleTags(String path, Tag[] value) { + return assertAddMultipleTags(path, object2Json(value), HttpURLConnection.HTTP_OK, TAGS_NULL); + } + + /** + * @see ITUtilTags#assertAddMultipleTags(String, String, int, Tag[]) + */ + public static Tag[] assertAddMultipleTags(String path, String json, int expectedResponseCode) { + return assertAddMultipleTags(path, json, expectedResponseCode, TAGS_NULL); + } + + /** + * Utility method to add the tags in the payload to the directory. + * + * @param path path + * @param json tags + * @param expectedResponseCode expected response code + * @param expected expected response tags + */ + public static Tag[] assertAddMultipleTags( + String path, String json, int expectedResponseCode, Tag[] expected) { + Tag[] actual = null; + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.POST, AuthorizationChoice.ADMIN, EndpointChoice.TAGS, path, json)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + if (HttpURLConnection.HTTP_OK == expectedResponseCode) { + actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); + } + if (expected != null) { + assertEqualsTags(expected, actual); + } + } catch (Exception e) { + fail(); } - /** - * @see ITUtilTags#assertCreateReplaceTag(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertCreateReplaceTag(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceTag(authorizationChoice, path, json, expectedResponseCode, TAG_NULL); + return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Utility method to remove tag with the given tag_name from the channel with the given + * channel_name. + * + * @param path path + */ + public static void assertRemoveTagSingleChannel(String path) { + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.DELETE, AuthorizationChoice.ADMIN, EndpointChoice.TAGS, path, null)); + + ITUtil.assertResponseLength2CodeOK(response); + } catch (Exception e) { + fail(); } - /** - * Utility method to create or completely replace the existing tag name with the payload data. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response tag - */ - public static Tag assertCreateReplaceTag(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Tag expected) { - Tag actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.TAGS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * @see ITUtilTags#assertRemoveTag(AuthorizationChoice, String, int) + */ + public static void assertRemoveTag(String path) { + assertRemoveTag(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); + } + + /** + * Utility method to remove tag with the given name from all channels. + * + * @param authorizationChoice authorization choice (none, user, admin) + * @param path path + * @param expectedResponseCode expected response code + */ + public static void assertRemoveTag( + AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { + try { + String[] response = + ITUtil.sendRequest( + ITUtil.buildRequest( + MethodChoice.DELETE, authorizationChoice, EndpointChoice.TAGS, path, null)); + + ITUtil.assertResponseLength2Code(response, expectedResponseCode); + } catch (Exception e) { + fail(); } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertAddTagSingleChannel(String, Tag, Tag) - */ - public static Tag assertAddTagSingleChannel(String path, Tag value) { - return assertAddTagSingleChannel(path, value, HttpURLConnection.HTTP_OK, TAG_NULL); - } - /** - * Utility method to add tag with the given tag_name to the channel with the given channel_name. - * - * @param path path - * @param value tag - * @param expectedResponseCode expected response code - * @param expected expected response tag - */ - public static Tag assertAddTagSingleChannel(String path, Tag value, int expectedResponseCode, Tag expected) { - Tag actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, AuthorizationChoice.ADMIN, EndpointChoice.TAGS, path, ITUtil.MAPPER.writeValueAsString(value))); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertCreateReplaceTags(AuthorizationChoice, String, String, int, Tag[]) - */ - public static Tag[] assertCreateReplaceTags(String path, Tag[] value) { - return assertCreateReplaceTags(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAGS_NULL); + } + + // ---------------------------------------------------------------------------------------------------- + + /** + * Assert that arrays are equal with same length and same content in each array position. + * + * @param actual actual array of Tag objects + * @param expected expected arbitrary number of Tag objects + */ + static void assertEqualsTags(Tag[] actual, Tag... expected) { + if (expected != null) { + assertNotNull(actual); + assertEquals(expected.length, actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } + } else { + assertNull(actual); } - /** - * @see ITUtilTags#assertCreateReplaceTags(AuthorizationChoice, String, String, int, Tag[]) - */ - public static Tag[] assertCreateReplaceTags(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertCreateReplaceTags(authorizationChoice, path, json, expectedResponseCode, TAGS_NULL); - } - /** - * Utility method to add the tags in the payload to the directory. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response tags - */ - public static Tag[] assertCreateReplaceTags(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Tag[] expected) { - Tag[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.PUT, authorizationChoice, EndpointChoice.TAGS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); - } - if (expected != null) { - assertEqualsTags(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertAddTagMultipleChannels(String path, Tag value) { - return assertAddTagMultipleChannels(AuthorizationChoice.ADMIN, path, object2Json(value), HttpURLConnection.HTTP_OK, TAG_NULL); - } - /** - * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertAddTagMultipleChannels(AuthorizationChoice authorizationChoice, String path, Tag value, int expectedResponseCode) { - return assertAddTagMultipleChannels(authorizationChoice, path, object2Json(value), expectedResponseCode, TAG_NULL); - } - /** - * @see ITUtilTags#assertAddTagMultipleChannels(AuthorizationChoice, String, String, int, Tag) - */ - public static Tag assertAddTagMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode) { - return assertAddTagMultipleChannels(authorizationChoice, path, json, expectedResponseCode, TAG_NULL); - } - /** - * Utility method to add tag with the given name to all channels in the payload data. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param json json - * @param expectedResponseCode expected response code - * @param expected expected response tag - */ - public static Tag assertAddTagMultipleChannels(AuthorizationChoice authorizationChoice, String path, String json, int expectedResponseCode, Tag expected) { - Tag actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, authorizationChoice, EndpointChoice.TAGS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag.class); - } - if (expected != null) { - assertEquals(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertAddMultipleTags(String, String, int, Tag[]) - */ - public static Tag[] assertAddMultipleTags(String path, Tag[] value) { - return assertAddMultipleTags(path, object2Json(value), HttpURLConnection.HTTP_OK, TAGS_NULL); - } - /** - * @see ITUtilTags#assertAddMultipleTags(String, String, int, Tag[]) - */ - public static Tag[] assertAddMultipleTags(String path, String json, int expectedResponseCode) { - return assertAddMultipleTags(path, json, expectedResponseCode, TAGS_NULL); - } - /** - * Utility method to add the tags in the payload to the directory. - * - * @param path path - * @param json tags - * @param expectedResponseCode expected response code - * @param expected expected response tags - */ - public static Tag[] assertAddMultipleTags(String path, String json, int expectedResponseCode, Tag[] expected) { - Tag[] actual = null; - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.POST, AuthorizationChoice.ADMIN, EndpointChoice.TAGS, path, json)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - if (HttpURLConnection.HTTP_OK == expectedResponseCode) { - actual = ITUtil.MAPPER.readValue(response[1], Tag[].class); - } - if (expected != null) { - assertEqualsTags(expected, actual); - } - } catch (Exception e) { - fail(); - } - return actual; - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Utility method to remove tag with the given tag_name from the channel with the given channel_name. - * - * @param path path - */ - public static void assertRemoveTagSingleChannel(String path) { - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.DELETE, AuthorizationChoice.ADMIN, EndpointChoice.TAGS, path, null)); - - ITUtil.assertResponseLength2CodeOK(response); - } catch (Exception e) { - fail(); - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * @see ITUtilTags#assertRemoveTag(AuthorizationChoice, String, int) - */ - public static void assertRemoveTag(String path) { - assertRemoveTag(AuthorizationChoice.ADMIN, path, HttpURLConnection.HTTP_OK); - } - /** - * Utility method to remove tag with the given name from all channels. - * - * @param authorizationChoice authorization choice (none, user, admin) - * @param path path - * @param expectedResponseCode expected response code - */ - public static void assertRemoveTag(AuthorizationChoice authorizationChoice, String path, int expectedResponseCode) { - try { - String[] response = ITUtil.sendRequest(ITUtil.buildRequest(MethodChoice.DELETE, authorizationChoice, EndpointChoice.TAGS, path, null)); - - ITUtil.assertResponseLength2Code(response, expectedResponseCode); - } catch (Exception e) { - fail(); - } - } - - // ---------------------------------------------------------------------------------------------------- - - /** - * Assert that arrays are equal with same length and same content in each array position. - * - * @param actual actual array of Tag objects - * @param expected expected arbitrary number of Tag objects - */ - static void assertEqualsTags(Tag[] actual, Tag... expected) { - if (expected != null) { - assertNotNull(actual); - assertEquals(expected.length, actual.length); - for (int i=0; i properties = List.of(testProperty0, testProperty1); - propertyManager.create(properties); - testChannel0.setProperties(properties); + // Create properties + Property testProperty0 = new Property("testProperty0", "testOwner", "testPropertyValue0"); + Property testProperty1 = new Property("testProperty1", "testOwner", "testPropertyValue1"); + List properties = List.of(testProperty0, testProperty1); + propertyManager.create(properties); + testChannel0.setProperties(properties); - // Create tag - Tag tag = new Tag("testTag", "testOwner"); - tagManager.create(List.of(tag)); - testChannel0.setTags(List.of(tag)); + // Create tag + Tag tag = new Tag("testTag", "testOwner"); + tagManager.create(List.of(tag)); + testChannel0.setTags(List.of(tag)); - // Create a simple channel - Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); + // Create a simple channel + Channel createdChannel0 = channelManager.create(testChannel0.getName(), testChannel0); - Channel expectedChannel = new Channel("testChannel0", "testOwner"); + Channel expectedChannel = new Channel("testChannel0", "testOwner"); - // Create properties - Property expProperty0 = new Property("testProperty0",null, "testPropertyValue0"); - Property expProperty1 = new Property("testProperty1",null, "testPropertyValue1"); - expectedChannel.setProperties(List.of(expProperty0, expProperty1)); + // Create properties + Property expProperty0 = new Property("testProperty0", null, "testPropertyValue0"); + Property expProperty1 = new Property("testProperty1", null, "testPropertyValue1"); + expectedChannel.setProperties(List.of(expProperty0, expProperty1)); - // Create tag - Tag expTag = new Tag("testTag", null); - expectedChannel.setTags(List.of(expTag)); + // Create tag + Tag expTag = new Tag("testTag", null); + expectedChannel.setTags(List.of(expTag)); - PVAURI uri = new PVAURI("uriname", "pva", "auth", ChannelFinderEpicsService.SERVICE_DESC, Map.of("_name", "*") ); - try { - PVAStructure result = pvaChannel.invoke(uri.cloneData()).get(30,TimeUnit.SECONDS); - List channels = NTXmlUtil.parse(result); - logger.log(Level.INFO, () -> "Result channel list " + channels); - Assertions.assertEquals(expectedChannel, channels.get(0)); - } catch (Exception e) { + PVAURI uri = + new PVAURI( + "uriname", "pva", "auth", ChannelFinderEpicsService.SERVICE_DESC, Map.of("_name", "*")); + try { + PVAStructure result = pvaChannel.invoke(uri.cloneData()).get(30, TimeUnit.SECONDS); + List channels = NTXmlUtil.parse(result); + logger.log(Level.INFO, () -> "Result channel list " + channels); + Assertions.assertEquals(expectedChannel, channels.get(0)); + } catch (Exception e) { - logger.log(Level.WARNING, e.getMessage(), e); - Assertions.fail(e); - } + logger.log(Level.WARNING, e.getMessage(), e); + Assertions.fail(e); } + } } diff --git a/src/test/java/org/phoebus/channelfinder/performance/ExistsPerformanceIT.java b/src/test/java/org/phoebus/channelfinder/performance/ExistsPerformanceIT.java index 42a27e2d..b25ee374 100644 --- a/src/test/java/org/phoebus/channelfinder/performance/ExistsPerformanceIT.java +++ b/src/test/java/org/phoebus/channelfinder/performance/ExistsPerformanceIT.java @@ -1,5 +1,6 @@ package org.phoebus.channelfinder.performance; +import com.google.common.collect.Lists; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.phoebus.channelfinder.ChannelRepository; @@ -7,28 +8,23 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; - -import com.google.common.collect.Lists; - /** * Performance tests for "exists" calls - * - * @author Kunal Shroff * + * @author Kunal Shroff */ @WebMvcTest(ChannelRepository.class) class ExistsPerformanceIT { - @Autowired - PopulateService service; + @Autowired PopulateService service; - @Autowired - ChannelRepository channelRepository; + @Autowired ChannelRepository channelRepository; - @Test - void channelExists() { - service.createDB(1); - Assertions.assertTrue(channelRepository.existsByIds(Lists.newArrayList(service.getChannelList()))); - service.cleanupDB(); - } + @Test + void channelExists() { + service.createDB(1); + Assertions.assertTrue( + channelRepository.existsByIds(Lists.newArrayList(service.getChannelList()))); + service.cleanupDB(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/performance/PopulateServiceIT.java b/src/test/java/org/phoebus/channelfinder/performance/PopulateServiceIT.java index f02417c8..4a393146 100644 --- a/src/test/java/org/phoebus/channelfinder/performance/PopulateServiceIT.java +++ b/src/test/java/org/phoebus/channelfinder/performance/PopulateServiceIT.java @@ -1,5 +1,6 @@ package org.phoebus.channelfinder.performance; +import java.net.URL; import org.junit.jupiter.api.Test; import org.phoebus.channelfinder.AuthorizationService; import org.phoebus.channelfinder.example.PopulateService; @@ -8,35 +9,29 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.TestPropertySource; -import java.net.URL; - -/** - * An class for creating the example database and testing the speed. - */ +/** An class for creating the example database and testing the speed. */ @WebMvcTest(AuthorizationService.class) @TestPropertySource(value = "classpath:performance_application.properties") class PopulateServiceIT { - @Autowired - PopulateService populateService; - @Test - @WithMockUser(username = "admin", roles = "CF-ADMINS") - void testCreateTagsAndProperties() { - final URL tagResource = getClass().getResource("/perf_tags.json"); - final URL propertyResource = getClass().getResource("/perf_properties.json"); - - populateService.createTagsAndProperties(tagResource, propertyResource); - } + @Autowired PopulateService populateService; - @Test - void testCreateDB() { - populateService.createDB(); - } + @Test + @WithMockUser(username = "admin", roles = "CF-ADMINS") + void testCreateTagsAndProperties() { + final URL tagResource = getClass().getResource("/perf_tags.json"); + final URL propertyResource = getClass().getResource("/perf_properties.json"); - @Test - void testCleanUpDB() { - populateService.cleanupDB(); - } + populateService.createTagsAndProperties(tagResource, propertyResource); + } + @Test + void testCreateDB() { + populateService.createDB(); + } + @Test + void testCleanUpDB() { + populateService.cleanupDB(); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorIT.java index 9f9ed0bd..7d3af327 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorIT.java @@ -1,7 +1,14 @@ package org.phoebus.channelfinder.processors; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -19,172 +26,181 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @WebMvcTest(AAChannelProcessor.class) @TestPropertySource(value = "classpath:application_test.properties") class AAChannelProcessorIT { - protected static Property archiveProperty = new Property("archive", "owner", "default"); - protected static Property activeProperty = new Property("pvStatus", "owner", "Active"); - protected static Property inactiveProperty = new Property("pvStatus", "owner", "Inactive"); - - @Autowired - AAChannelProcessor aaChannelProcessor; - - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; - - @NotNull - private static Stream processSource() { - return Stream.of( - Arguments.of( - new Channel("PVArchivedActive", "owner", List.of(archiveProperty, activeProperty), List.of()), - "Being archived", - "", - ""), - Arguments.of( - new Channel("PVPausedActive", "owner", List.of(archiveProperty, activeProperty), List.of()), - "Paused", - "resumeArchivingPV", - "[\"PVPausedActive\"]"), - Arguments.of( - new Channel("PVNoneActive", "owner", List.of(archiveProperty, activeProperty), List.of()), - "Not being archived", - "archivePV", - "[{\"pv\":\"PVNoneActive\"}]"), - Arguments.of( - new Channel( - "PVArchivedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Being archived", - "pauseArchivingPV", - "[\"PVArchivedInactive\"]"), - Arguments.of( - new Channel("PVPausedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Paused", - "", - ""), - Arguments.of( - new Channel("PVNoneInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Not being archived", - "", - ""), - Arguments.of( - new Channel("PVArchivedNotag", "owner", List.of(), List.of()), - "Being archived", - "pauseArchivingPV", - "[\"PVArchivedNotag\"]")); - } - - public static void paramableAAChannelProcessorTest( - MockWebServer mockArchiverAppliance, - ObjectMapper objectMapper, - ChannelProcessor aaChannelProcessor, - List channels, - String archiveStatus, - String archiverEndpoint, - String submissionBody) - throws JsonProcessingException, InterruptedException { - // Request to version - Map versions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0"); - mockArchiverAppliance.enqueue(new MockResponse() - .setBody(objectMapper.writeValueAsString(versions)) - .addHeader("Content-Type", "application/json")); - - // Request to policies - Map policyList = Map.of("policy", "description"); - mockArchiverAppliance.enqueue(new MockResponse() - .setBody(objectMapper.writeValueAsString(policyList)) - .addHeader("Content-Type", "application/json")); - - if (!archiveStatus.isEmpty()) { - - // Request to archiver status - List> archivePVStatuses = - channels.stream().map(channel -> Map.of("pvName", channel.getName(), "status", archiveStatus)).toList(); - mockArchiverAppliance.enqueue(new MockResponse() - .setBody(objectMapper.writeValueAsString(archivePVStatuses)) - .addHeader("Content-Type", "application/json")); - } - if (!archiverEndpoint.isEmpty()) { - // Request to archiver to archive - List> archiverResponse = - channels.stream().map(channel -> Map.of("pvName", channel.getName(), "status", "Archive request submitted")).toList(); - mockArchiverAppliance.enqueue(new MockResponse() - .setBody(objectMapper.writeValueAsString(archiverResponse)) - .addHeader("Content-Type", "application/json")); - } - - long count = aaChannelProcessor.process(channels); - assertEquals(count, archiverEndpoint.isEmpty() ? 0 : channels.size()); - - int expectedRequests = 1; - RecordedRequest requestVersion = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestVersion != null; - assertEquals("/mgmt/bpl/getVersions", requestVersion.getPath()); - - expectedRequests += 1; - RecordedRequest requestPolicy = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestPolicy != null; - assertEquals("/mgmt/bpl/getPolicyList", requestPolicy.getPath()); - - if (!archiveStatus.isEmpty()) { - expectedRequests += 1; - RecordedRequest requestStatus = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestStatus != null; - assert requestStatus.getRequestUrl() != null; - assertEquals("/mgmt/bpl/getPVStatus", requestStatus.getRequestUrl().encodedPath()); - } - - if (!archiverEndpoint.isEmpty()) { - expectedRequests += 1; - RecordedRequest requestAction = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestAction != null; - assertEquals("/mgmt/bpl/" + archiverEndpoint, requestAction.getPath()); - assertEquals(submissionBody, requestAction.getBody().readUtf8()); - } - - assertEquals(mockArchiverAppliance.getRequestCount(), expectedRequests); + protected static Property archiveProperty = new Property("archive", "owner", "default"); + protected static Property activeProperty = new Property("pvStatus", "owner", "Active"); + protected static Property inactiveProperty = new Property("pvStatus", "owner", "Inactive"); + + @Autowired AAChannelProcessor aaChannelProcessor; + + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; + + @NotNull + private static Stream processSource() { + return Stream.of( + Arguments.of( + new Channel( + "PVArchivedActive", "owner", List.of(archiveProperty, activeProperty), List.of()), + "Being archived", + "", + ""), + Arguments.of( + new Channel( + "PVPausedActive", "owner", List.of(archiveProperty, activeProperty), List.of()), + "Paused", + "resumeArchivingPV", + "[\"PVPausedActive\"]"), + Arguments.of( + new Channel( + "PVNoneActive", "owner", List.of(archiveProperty, activeProperty), List.of()), + "Not being archived", + "archivePV", + "[{\"pv\":\"PVNoneActive\"}]"), + Arguments.of( + new Channel( + "PVArchivedInactive", + "owner", + List.of(archiveProperty, inactiveProperty), + List.of()), + "Being archived", + "pauseArchivingPV", + "[\"PVArchivedInactive\"]"), + Arguments.of( + new Channel( + "PVPausedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), + "Paused", + "", + ""), + Arguments.of( + new Channel( + "PVNoneInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), + "Not being archived", + "", + ""), + Arguments.of( + new Channel("PVArchivedNotag", "owner", List.of(), List.of()), + "Being archived", + "pauseArchivingPV", + "[\"PVArchivedNotag\"]")); + } + + public static void paramableAAChannelProcessorTest( + MockWebServer mockArchiverAppliance, + ObjectMapper objectMapper, + ChannelProcessor aaChannelProcessor, + List channels, + String archiveStatus, + String archiverEndpoint, + String submissionBody) + throws JsonProcessingException, InterruptedException { + // Request to version + Map versions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0"); + mockArchiverAppliance.enqueue( + new MockResponse() + .setBody(objectMapper.writeValueAsString(versions)) + .addHeader("Content-Type", "application/json")); + + // Request to policies + Map policyList = Map.of("policy", "description"); + mockArchiverAppliance.enqueue( + new MockResponse() + .setBody(objectMapper.writeValueAsString(policyList)) + .addHeader("Content-Type", "application/json")); + + if (!archiveStatus.isEmpty()) { + + // Request to archiver status + List> archivePVStatuses = + channels.stream() + .map(channel -> Map.of("pvName", channel.getName(), "status", archiveStatus)) + .toList(); + mockArchiverAppliance.enqueue( + new MockResponse() + .setBody(objectMapper.writeValueAsString(archivePVStatuses)) + .addHeader("Content-Type", "application/json")); } - - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); - - objectMapper = new ObjectMapper(); + if (!archiverEndpoint.isEmpty()) { + // Request to archiver to archive + List> archiverResponse = + channels.stream() + .map( + channel -> + Map.of("pvName", channel.getName(), "status", "Archive request submitted")) + .toList(); + mockArchiverAppliance.enqueue( + new MockResponse() + .setBody(objectMapper.writeValueAsString(archiverResponse)) + .addHeader("Content-Type", "application/json")); } - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); + long count = aaChannelProcessor.process(channels); + assertEquals(count, archiverEndpoint.isEmpty() ? 0 : channels.size()); + + int expectedRequests = 1; + RecordedRequest requestVersion = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestVersion.getPath()); + + expectedRequests += 1; + RecordedRequest requestPolicy = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestPolicy.getPath()); + + if (!archiveStatus.isEmpty()) { + expectedRequests += 1; + RecordedRequest requestStatus = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestStatus != null; + assert requestStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestStatus.getRequestUrl().encodedPath()); } - @Test - void testProcessNoPVs() throws JsonProcessingException { - aaChannelProcessor.process(List.of()); - - assertEquals(mockArchiverAppliance.getRequestCount(), 0); + if (!archiverEndpoint.isEmpty()) { + expectedRequests += 1; + RecordedRequest requestAction = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestAction != null; + assertEquals("/mgmt/bpl/" + archiverEndpoint, requestAction.getPath()); + assertEquals(submissionBody, requestAction.getBody().readUtf8()); } - @ParameterizedTest - @MethodSource("processSource") - void testProcessNotArchivedActive( - Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) - throws JsonProcessingException, InterruptedException { - paramableAAChannelProcessorTest( - mockArchiverAppliance, - objectMapper, - aaChannelProcessor, - List.of(channel), - archiveStatus, - archiverEndpoint, - submissionBody); - } + assertEquals(mockArchiverAppliance.getRequestCount(), expectedRequests); + } + + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); + + objectMapper = new ObjectMapper(); + } + + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } + + @Test + void testProcessNoPVs() throws JsonProcessingException { + aaChannelProcessor.process(List.of()); + + assertEquals(mockArchiverAppliance.getRequestCount(), 0); + } + + @ParameterizedTest + @MethodSource("processSource") + void testProcessNotArchivedActive( + Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) + throws JsonProcessingException, InterruptedException { + paramableAAChannelProcessorTest( + mockArchiverAppliance, + objectMapper, + aaChannelProcessor, + List.of(channel), + archiveStatus, + archiverEndpoint, + submissionBody); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java index d26910c5..1cc76071 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java @@ -1,7 +1,21 @@ package org.phoebus.channelfinder.processors; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -17,66 +31,59 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; - @WebMvcTest(AAChannelProcessor.class) @TestPropertySource(value = "classpath:application_test_multi.properties") class AAChannelProcessorMultiArchiverIT { - public static final String BEING_ARCHIVED = "Being archived"; - public static final String PAUSED = "Paused"; - public static final String NOT_BEING_ARCHIVED = "Not being archived"; - public static final String OWNER = "owner"; - @Autowired - AAChannelProcessor aaChannelProcessor; - - MockWebServer mockQueryArchiverAppliance; - MockWebServer mockPostArchiverAppliance; - ObjectMapper objectMapper; - - @BeforeEach - void setUp() throws IOException { - mockQueryArchiverAppliance = new MockWebServer(); - mockQueryArchiverAppliance.start(17664); - mockPostArchiverAppliance = new MockWebServer(); - mockPostArchiverAppliance.start(17665); - - objectMapper = new ObjectMapper(); - } - - @AfterEach - void teardown() throws IOException { - mockQueryArchiverAppliance.shutdown(); - mockPostArchiverAppliance.shutdown(); - } - - static Stream provideArguments() { - List channels = List.of( - new Channel("PVArchivedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVPausedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVNoneActive0", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVArchivedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), - new Channel("PVPausedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), - new Channel("PVNoneInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + public static final String BEING_ARCHIVED = "Being archived"; + public static final String PAUSED = "Paused"; + public static final String NOT_BEING_ARCHIVED = "Not being archived"; + public static final String OWNER = "owner"; + @Autowired AAChannelProcessor aaChannelProcessor; + + MockWebServer mockQueryArchiverAppliance; + MockWebServer mockPostArchiverAppliance; + ObjectMapper objectMapper; + + @BeforeEach + void setUp() throws IOException { + mockQueryArchiverAppliance = new MockWebServer(); + mockQueryArchiverAppliance.start(17664); + mockPostArchiverAppliance = new MockWebServer(); + mockPostArchiverAppliance.start(17665); + + objectMapper = new ObjectMapper(); + } + + @AfterEach + void teardown() throws IOException { + mockQueryArchiverAppliance.shutdown(); + mockPostArchiverAppliance.shutdown(); + } + + static Stream provideArguments() { + List channels = + List.of( + new Channel( + "PVArchivedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVPausedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVNoneActive0", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVArchivedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel( + "PVPausedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel( + "PVNoneInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), new Channel("PVArchivedNotag", OWNER, List.of(), List.of()), - new Channel("PVNoneActive1", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVNoneActive2", OWNER, List.of(archiveProperty, activeProperty), List.of()) - ); + new Channel( + "PVNoneActive1", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVNoneActive2", OWNER, List.of(archiveProperty, activeProperty), List.of())); - Map namesToStatuses = Map.of( + Map namesToStatuses = + Map.of( "PVArchivedActive", BEING_ARCHIVED, "PVPausedActive", PAUSED, "PVNoneActive0", NOT_BEING_ARCHIVED, @@ -85,181 +92,201 @@ static Stream provideArguments() { "PVNoneInactive", NOT_BEING_ARCHIVED, "PVArchivedNotag", BEING_ARCHIVED, "PVNoneActive1", NOT_BEING_ARCHIVED, - "PVNoneActive2", NOT_BEING_ARCHIVED - ); - Map> actionsToNames = Map.of( + "PVNoneActive2", NOT_BEING_ARCHIVED); + Map> actionsToNames = + Map.of( ArchiveAction.RESUME, List.of("PVPausedActive"), ArchiveAction.PAUSE, List.of("PVArchivedInactive", "PVArchivedNotag"), - ArchiveAction.ARCHIVE, List.of("PVNoneActive0", "PVNoneActive1", "PVNoneActive2") - ); - int expectedProcessedChannels = 12; - - List massPVNames = IntStream.range(1, 100).mapToObj(i -> "PV" + i).toList(); - return Stream.of( - Arguments.of(channels, namesToStatuses, actionsToNames, expectedProcessedChannels), - Arguments.of( - massPVNames.stream().map(s -> new Channel(s, OWNER, List.of(archiveProperty, activeProperty), List.of())).toList(), - massPVNames.stream().collect(Collectors.toMap(String::toString, e -> NOT_BEING_ARCHIVED)), - Map.of(ArchiveAction.ARCHIVE, massPVNames), - massPVNames.size() - )); - } - - @ParameterizedTest - @MethodSource("provideArguments") - void testProcessMultiArchivers(List channels, - Map namesToStatuses, - Map> actionsToNames, - int expectedProcessedChannels) - throws JsonProcessingException, InterruptedException { - - // Request to version - Map queryVersions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Query Support"); - mockQueryArchiverAppliance.enqueue(new MockResponse() + ArchiveAction.ARCHIVE, List.of("PVNoneActive0", "PVNoneActive1", "PVNoneActive2")); + int expectedProcessedChannels = 12; + + List massPVNames = IntStream.range(1, 100).mapToObj(i -> "PV" + i).toList(); + return Stream.of( + Arguments.of(channels, namesToStatuses, actionsToNames, expectedProcessedChannels), + Arguments.of( + massPVNames.stream() + .map( + s -> new Channel(s, OWNER, List.of(archiveProperty, activeProperty), List.of())) + .toList(), + massPVNames.stream() + .collect(Collectors.toMap(String::toString, e -> NOT_BEING_ARCHIVED)), + Map.of(ArchiveAction.ARCHIVE, massPVNames), + massPVNames.size())); + } + + @ParameterizedTest + @MethodSource("provideArguments") + void testProcessMultiArchivers( + List channels, + Map namesToStatuses, + Map> actionsToNames, + int expectedProcessedChannels) + throws JsonProcessingException, InterruptedException { + + // Request to version + Map queryVersions = + Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Query Support"); + mockQueryArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(queryVersions)) .addHeader("Content-Type", "application/json")); - // Request to policies - Map policyList = Map.of("policy", "description"); - mockQueryArchiverAppliance.enqueue(new MockResponse() + // Request to policies + Map policyList = Map.of("policy", "description"); + mockQueryArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(policyList)) .addHeader("Content-Type", "application/json")); - // Request to archiver status - List> archivePVStatuses = - namesToStatuses.entrySet().stream().map(entry -> Map.of("pvName", entry.getKey(), "status", entry.getValue())).toList(); - mockQueryArchiverAppliance.enqueue(new MockResponse() + // Request to archiver status + List> archivePVStatuses = + namesToStatuses.entrySet().stream() + .map(entry -> Map.of("pvName", entry.getKey(), "status", entry.getValue())) + .toList(); + mockQueryArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archivePVStatuses)) .addHeader("Content-Type", "application/json")); - // Requests to archiver - actionsToNames.forEach((key, value) -> { - List> archiverResponse = - value.stream().map(channel -> Map.of("pvName", channel, "status", key + " request submitted")).toList(); - try { - mockQueryArchiverAppliance.enqueue(new MockResponse() + // Requests to archiver + actionsToNames.forEach( + (key, value) -> { + List> archiverResponse = + value.stream() + .map(channel -> Map.of("pvName", channel, "status", key + " request submitted")) + .toList(); + try { + mockQueryArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archiverResponse)) .addHeader("Content-Type", "application/json")); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } }); - - // Request to query version - Map postVersions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Post Support"); - mockPostArchiverAppliance.enqueue(new MockResponse() + // Request to query version + Map postVersions = + Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Post Support"); + mockPostArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(postVersions)) .addHeader("Content-Type", "application/json")); - // Request to policies - mockPostArchiverAppliance.enqueue(new MockResponse() + // Request to policies + mockPostArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(policyList)) .addHeader("Content-Type", "application/json")); - // Request to archiver status - mockPostArchiverAppliance.enqueue(new MockResponse() + // Request to archiver status + mockPostArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archivePVStatuses)) .addHeader("Content-Type", "application/json")); - // Requests to archiver - actionsToNames.forEach((key, value) -> { - List> archiverResponse = - value.stream().map(channel -> Map.of("pvName", channel, "status", key + " request submitted")).toList(); - try { - mockPostArchiverAppliance.enqueue(new MockResponse() + // Requests to archiver + actionsToNames.forEach( + (key, value) -> { + List> archiverResponse = + value.stream() + .map(channel -> Map.of("pvName", channel, "status", key + " request submitted")) + .toList(); + try { + mockPostArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archiverResponse)) .addHeader("Content-Type", "application/json")); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } }); - aaChannelProcessor.process(channels); - - AtomicInteger expectedQueryRequests = new AtomicInteger(1); - RecordedRequest requestQueryVersion = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestQueryVersion != null; - assertEquals("/mgmt/bpl/getVersions", requestQueryVersion.getPath()); - - expectedQueryRequests.addAndGet(1); - RecordedRequest requestQueryPolicy = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestQueryPolicy != null; - assertEquals("/mgmt/bpl/getPolicyList", requestQueryPolicy.getPath()); - - expectedQueryRequests.addAndGet(1); - RecordedRequest requestQueryStatus = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestQueryStatus != null; - assert requestQueryStatus.getRequestUrl() != null; - assertEquals("/mgmt/bpl/getPVStatus", requestQueryStatus.getRequestUrl().encodedPath()); - - AtomicInteger expectedPostRequests = new AtomicInteger(1); - RecordedRequest requestPostVersion = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestPostVersion != null; - assertEquals("/mgmt/bpl/getVersions", requestPostVersion.getPath()); - - expectedPostRequests.addAndGet(1); - RecordedRequest requestPostPolicy = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestPostPolicy != null; - assertEquals("/mgmt/bpl/getPolicyList", requestPostPolicy.getPath()); - - expectedPostRequests.addAndGet(1); - RecordedRequest requestPostStatus = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestPostStatus != null; - assert requestPostStatus.getRequestUrl() != null; - assertEquals("/mgmt/bpl/getPVStatus", requestPostStatus.getRequestUrl().encodedPath()); - - while (mockQueryArchiverAppliance.getRequestCount() > 0) { - RecordedRequest requestAction = null; - try { - requestAction = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (requestAction == null) { - break; - } - expectedQueryRequests.addAndGet(1); - assert requestAction.getPath() != null; - assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); - ArchiveAction key = actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); - String body = requestAction.getBody().readUtf8(); - actionsToNames.get(key).forEach(pv -> - assertTrue(body.contains(pv)) - ); - } - - while (mockPostArchiverAppliance.getRequestCount() > 0) { - RecordedRequest requestAction = null; - try { - requestAction = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (requestAction == null) { - break; - } - expectedPostRequests.addAndGet(1); - assert requestAction.getPath() != null; - assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); - ArchiveAction key = actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); - String body = requestAction.getBody().readUtf8(); - actionsToNames.get(key).forEach(pv -> - assertTrue(body.contains(pv)) - ); - } + aaChannelProcessor.process(channels); + + AtomicInteger expectedQueryRequests = new AtomicInteger(1); + RecordedRequest requestQueryVersion = + mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestQueryVersion.getPath()); + + expectedQueryRequests.addAndGet(1); + RecordedRequest requestQueryPolicy = + mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestQueryPolicy.getPath()); + + expectedQueryRequests.addAndGet(1); + RecordedRequest requestQueryStatus = + mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryStatus != null; + assert requestQueryStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestQueryStatus.getRequestUrl().encodedPath()); + + AtomicInteger expectedPostRequests = new AtomicInteger(1); + RecordedRequest requestPostVersion = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestPostVersion.getPath()); + + expectedPostRequests.addAndGet(1); + RecordedRequest requestPostPolicy = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestPostPolicy.getPath()); + + expectedPostRequests.addAndGet(1); + RecordedRequest requestPostStatus = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostStatus != null; + assert requestPostStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestPostStatus.getRequestUrl().encodedPath()); + + while (mockQueryArchiverAppliance.getRequestCount() > 0) { + RecordedRequest requestAction = null; + try { + requestAction = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (requestAction == null) { + break; + } + expectedQueryRequests.addAndGet(1); + assert requestAction.getPath() != null; + assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); + ArchiveAction key = + actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); + String body = requestAction.getBody().readUtf8(); + actionsToNames.get(key).forEach(pv -> assertTrue(body.contains(pv))); + } - assertEquals(mockPostArchiverAppliance.getRequestCount(), expectedPostRequests.get()); - assertEquals(mockQueryArchiverAppliance.getRequestCount(), expectedQueryRequests.get()); + while (mockPostArchiverAppliance.getRequestCount() > 0) { + RecordedRequest requestAction = null; + try { + requestAction = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (requestAction == null) { + break; + } + expectedPostRequests.addAndGet(1); + assert requestAction.getPath() != null; + assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); + ArchiveAction key = + actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); + String body = requestAction.getBody().readUtf8(); + actionsToNames.get(key).forEach(pv -> assertTrue(body.contains(pv))); } + assertEquals(mockPostArchiverAppliance.getRequestCount(), expectedPostRequests.get()); + assertEquals(mockQueryArchiverAppliance.getRequestCount(), expectedQueryRequests.get()); + } - public ArchiveAction actionFromEndpoint(final String endpoint) { - for (ArchiveAction action : ArchiveAction.values()) { - if (action.getEndpoint().equals(endpoint)) { - return action; - } - } - return null; + public ArchiveAction actionFromEndpoint(final String endpoint) { + for (ArchiveAction action : ArchiveAction.values()) { + if (action.getEndpoint().equals(endpoint)) { + return action; + } } + return null; + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java index 9c63f159..9e81bb35 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java @@ -1,7 +1,21 @@ package org.phoebus.channelfinder.processors; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -17,62 +31,55 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; - @WebMvcTest(AAChannelProcessor.class) @TestPropertySource(value = "classpath:application_test.properties") class AAChannelProcessorMultiIT { - public static final String BEING_ARCHIVED = "Being archived"; - public static final String PAUSED = "Paused"; - public static final String NOT_BEING_ARCHIVED = "Not being archived"; - public static final String OWNER = "owner"; - @Autowired - AAChannelProcessor aaChannelProcessor; - - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; - - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); - - objectMapper = new ObjectMapper(); - } - - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); - } - - static Stream provideArguments() { - List channels = List.of( - new Channel("PVArchivedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVPausedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVNoneActive0", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVArchivedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), - new Channel("PVPausedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), - new Channel("PVNoneInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + public static final String BEING_ARCHIVED = "Being archived"; + public static final String PAUSED = "Paused"; + public static final String NOT_BEING_ARCHIVED = "Not being archived"; + public static final String OWNER = "owner"; + @Autowired AAChannelProcessor aaChannelProcessor; + + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; + + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); + + objectMapper = new ObjectMapper(); + } + + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } + + static Stream provideArguments() { + List channels = + List.of( + new Channel( + "PVArchivedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVPausedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVNoneActive0", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVArchivedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel( + "PVPausedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel( + "PVNoneInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), new Channel("PVArchivedNotag", OWNER, List.of(), List.of()), - new Channel("PVNoneActive1", OWNER, List.of(archiveProperty, activeProperty), List.of()), - new Channel("PVNoneActive2", OWNER, List.of(archiveProperty, activeProperty), List.of()) - ); + new Channel( + "PVNoneActive1", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel( + "PVNoneActive2", OWNER, List.of(archiveProperty, activeProperty), List.of())); - Map namesToStatuses = Map.of( + Map namesToStatuses = + Map.of( "PVArchivedActive", BEING_ARCHIVED, "PVPausedActive", PAUSED, "PVNoneActive0", NOT_BEING_ARCHIVED, @@ -81,122 +88,133 @@ static Stream provideArguments() { "PVNoneInactive", NOT_BEING_ARCHIVED, "PVArchivedNotag", BEING_ARCHIVED, "PVNoneActive1", NOT_BEING_ARCHIVED, - "PVNoneActive2", NOT_BEING_ARCHIVED - ); - Map> actionsToNames = Map.of( + "PVNoneActive2", NOT_BEING_ARCHIVED); + Map> actionsToNames = + Map.of( ArchiveAction.RESUME, List.of("PVPausedActive"), ArchiveAction.PAUSE, List.of("PVArchivedInactive", "PVArchivedNotag"), - ArchiveAction.ARCHIVE, List.of("PVNoneActive0", "PVNoneActive1", "PVNoneActive2") - ); - int expectedProcessedChannels = 6; - - List massPVNames = IntStream.range(1, 100).mapToObj(i -> "PV" + i).toList(); - return Stream.of( - Arguments.of(channels, namesToStatuses, actionsToNames, expectedProcessedChannels), - Arguments.of( - massPVNames.stream().map(s -> new Channel(s, OWNER, List.of(archiveProperty, activeProperty), List.of())).toList(), - massPVNames.stream().collect(Collectors.toMap(String::toString, e -> NOT_BEING_ARCHIVED)), - Map.of(ArchiveAction.ARCHIVE, massPVNames), - massPVNames.size() - )); - } - - @ParameterizedTest - @MethodSource("provideArguments") - void testProcessMulti(List channels, - Map namesToStatuses, - Map> actionsToNames, - int expectedProcessedChannels) - throws JsonProcessingException, InterruptedException { - - // Request to version - Map versions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0"); - mockArchiverAppliance.enqueue(new MockResponse() + ArchiveAction.ARCHIVE, List.of("PVNoneActive0", "PVNoneActive1", "PVNoneActive2")); + int expectedProcessedChannels = 6; + + List massPVNames = IntStream.range(1, 100).mapToObj(i -> "PV" + i).toList(); + return Stream.of( + Arguments.of(channels, namesToStatuses, actionsToNames, expectedProcessedChannels), + Arguments.of( + massPVNames.stream() + .map( + s -> new Channel(s, OWNER, List.of(archiveProperty, activeProperty), List.of())) + .toList(), + massPVNames.stream() + .collect(Collectors.toMap(String::toString, e -> NOT_BEING_ARCHIVED)), + Map.of(ArchiveAction.ARCHIVE, massPVNames), + massPVNames.size())); + } + + @ParameterizedTest + @MethodSource("provideArguments") + void testProcessMulti( + List channels, + Map namesToStatuses, + Map> actionsToNames, + int expectedProcessedChannels) + throws JsonProcessingException, InterruptedException { + + // Request to version + Map versions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0"); + mockArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(versions)) .addHeader("Content-Type", "application/json")); - // Request to policies - Map policyList = Map.of("policy", "description"); - mockArchiverAppliance.enqueue(new MockResponse() + // Request to policies + Map policyList = Map.of("policy", "description"); + mockArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(policyList)) .addHeader("Content-Type", "application/json")); - // Request to archiver status - List> archivePVStatuses = - namesToStatuses.entrySet().stream().map(entry -> Map.of("pvName", entry.getKey(), "status", entry.getValue())).toList(); - mockArchiverAppliance.enqueue(new MockResponse() + // Request to archiver status + List> archivePVStatuses = + namesToStatuses.entrySet().stream() + .map(entry -> Map.of("pvName", entry.getKey(), "status", entry.getValue())) + .toList(); + mockArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archivePVStatuses)) .addHeader("Content-Type", "application/json")); - // Requests to archiver - actionsToNames.forEach((key, value) -> { - List> archiverResponse = - value.stream().map(channel -> Map.of("pvName", channel, "status", key + " request submitted")).toList(); - try { - mockArchiverAppliance.enqueue(new MockResponse() + // Requests to archiver + actionsToNames.forEach( + (key, value) -> { + List> archiverResponse = + value.stream() + .map(channel -> Map.of("pvName", channel, "status", key + " request submitted")) + .toList(); + try { + mockArchiverAppliance.enqueue( + new MockResponse() .setBody(objectMapper.writeValueAsString(archiverResponse)) .addHeader("Content-Type", "application/json")); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } }); - long count = aaChannelProcessor.process(channels); - assertEquals(count, expectedProcessedChannels); - - AtomicInteger expectedRequests = new AtomicInteger(1); - RecordedRequest requestVersion = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestVersion != null; - assertEquals("/mgmt/bpl/getVersions", requestVersion.getPath()); - - expectedRequests.addAndGet(1); - RecordedRequest requestPolicy = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestPolicy != null; - assertEquals("/mgmt/bpl/getPolicyList", requestPolicy.getPath()); - - expectedRequests.addAndGet(1); - RecordedRequest requestStatus = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - assert requestStatus != null; - assert requestStatus.getRequestUrl() != null; - assertEquals("/mgmt/bpl/getPVStatus", requestStatus.getRequestUrl().encodedPath()); - String pvStatusRequestParameter = requestStatus.getRequestUrl().queryParameter("pv"); - namesToStatuses.keySet().forEach( + long count = aaChannelProcessor.process(channels); + assertEquals(count, expectedProcessedChannels); + + AtomicInteger expectedRequests = new AtomicInteger(1); + RecordedRequest requestVersion = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestVersion.getPath()); + + expectedRequests.addAndGet(1); + RecordedRequest requestPolicy = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestPolicy.getPath()); + + expectedRequests.addAndGet(1); + RecordedRequest requestStatus = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestStatus != null; + assert requestStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestStatus.getRequestUrl().encodedPath()); + String pvStatusRequestParameter = requestStatus.getRequestUrl().queryParameter("pv"); + namesToStatuses + .keySet() + .forEach( name -> { - assert pvStatusRequestParameter != null; - assertTrue(pvStatusRequestParameter.contains(name)); - } - ); - - while (mockArchiverAppliance.getRequestCount() > 0) { - RecordedRequest requestAction = null; - try { - requestAction = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (requestAction == null) { - break; - } - expectedRequests.addAndGet(1); - assert requestAction.getPath() != null; - assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); - ArchiveAction key = actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); - String body = requestAction.getBody().readUtf8(); - actionsToNames.get(key).forEach(pv -> - assertTrue(body.contains(pv)) - ); - } - - assertEquals(mockArchiverAppliance.getRequestCount(), expectedRequests.get()); + assert pvStatusRequestParameter != null; + assertTrue(pvStatusRequestParameter.contains(name)); + }); + + while (mockArchiverAppliance.getRequestCount() > 0) { + RecordedRequest requestAction = null; + try { + requestAction = mockArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (requestAction == null) { + break; + } + expectedRequests.addAndGet(1); + assert requestAction.getPath() != null; + assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); + ArchiveAction key = + actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); + String body = requestAction.getBody().readUtf8(); + actionsToNames.get(key).forEach(pv -> assertTrue(body.contains(pv))); } + assertEquals(mockArchiverAppliance.getRequestCount(), expectedRequests.get()); + } - public ArchiveAction actionFromEndpoint(final String endpoint) { - for (ArchiveAction action : ArchiveAction.values()) { - if (action.getEndpoint().equals(endpoint)) { - return action; - } - } - return null; + public ArchiveAction actionFromEndpoint(final String endpoint) { + for (ArchiveAction action : ArchiveAction.values()) { + if (action.getEndpoint().equals(endpoint)) { + return action; + } } + return null; + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoDefaultIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoDefaultIT.java index c5d3de56..2a5eb0c8 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoDefaultIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoDefaultIT.java @@ -1,7 +1,14 @@ package org.phoebus.channelfinder.processors; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -15,70 +22,63 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; - @WebMvcTest(AAChannelProcessor.class) -@TestPropertySource(locations = "classpath:application_test.properties", properties = "aa.urls:{'default': '','aa': 'http://localhost:17665'}") +@TestPropertySource( + locations = "classpath:application_test.properties", + properties = "aa.urls:{'default': '','aa': 'http://localhost:17665'}") class AAChannelProcessorNoDefaultIT { - protected static Property archiverProperty = new Property("archiver", "owner", "aa"); + protected static Property archiverProperty = new Property("archiver", "owner", "aa"); - @Autowired - AAChannelProcessor aaChannelProcessor; + @Autowired AAChannelProcessor aaChannelProcessor; - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; - private static Stream processNoPauseSource() { + private static Stream processNoPauseSource() { - return Stream.of( - Arguments.of( - new Channel("PVNoneActive", "owner", List.of(archiveProperty, activeProperty), List.of()), - "", - "", - ""), - Arguments.of( - new Channel("PVNoneActiveArchiver", "owner", List.of(archiveProperty, activeProperty, archiverProperty), List.of()), - "Not being archived", - "archivePV", - "[{\"pv\":\"PVNoneActiveArchiver\"}]") - ); - } + return Stream.of( + Arguments.of( + new Channel( + "PVNoneActive", "owner", List.of(archiveProperty, activeProperty), List.of()), + "", + "", + ""), + Arguments.of( + new Channel( + "PVNoneActiveArchiver", + "owner", + List.of(archiveProperty, activeProperty, archiverProperty), + List.of()), + "Not being archived", + "archivePV", + "[{\"pv\":\"PVNoneActiveArchiver\"}]")); + } - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); - objectMapper = new ObjectMapper(); - } + objectMapper = new ObjectMapper(); + } - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); - } + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } - @ParameterizedTest - @MethodSource("processNoPauseSource") - void testProcessNotArchivedActive( - Channel channel, - String archiveStatus, - String archiverEndpoint, - String submissionBody) - throws JsonProcessingException, InterruptedException { - paramableAAChannelProcessorTest( - mockArchiverAppliance, - objectMapper, - aaChannelProcessor, - List.of(channel), - archiveStatus, - archiverEndpoint, - submissionBody - ); - } + @ParameterizedTest + @MethodSource("processNoPauseSource") + void testProcessNotArchivedActive( + Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) + throws JsonProcessingException, InterruptedException { + paramableAAChannelProcessorTest( + mockArchiverAppliance, + objectMapper, + aaChannelProcessor, + List.of(channel), + archiveStatus, + archiverEndpoint, + submissionBody); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoPauseIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoPauseIT.java index 75fe7bf1..410f504f 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoPauseIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorNoPauseIT.java @@ -1,7 +1,14 @@ package org.phoebus.channelfinder.processors; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -14,68 +21,57 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; - @WebMvcTest(AAChannelProcessor.class) -@TestPropertySource(locations = "classpath:application_test.properties", properties = "aa.auto_pause=none") +@TestPropertySource( + locations = "classpath:application_test.properties", + properties = "aa.auto_pause=none") class AAChannelProcessorNoPauseIT { - @Autowired - AAChannelProcessor aaChannelProcessor; + @Autowired AAChannelProcessor aaChannelProcessor; - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; - private static Stream processNoPauseSource() { + private static Stream processNoPauseSource() { - return Stream.of( - Arguments.of( - new Channel( - "PVArchivedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Being archived", - "", - ""), - Arguments.of( - new Channel("PVArchivedNotag", "owner", List.of(), List.of()), - "", - "", - "")); - } + return Stream.of( + Arguments.of( + new Channel( + "PVArchivedInactive", + "owner", + List.of(archiveProperty, inactiveProperty), + List.of()), + "Being archived", + "", + ""), + Arguments.of(new Channel("PVArchivedNotag", "owner", List.of(), List.of()), "", "", "")); + } - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); - objectMapper = new ObjectMapper(); - } + objectMapper = new ObjectMapper(); + } - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); - } + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } - @ParameterizedTest - @MethodSource("processNoPauseSource") - void testProcessNotArchivedActive( - Channel channel, - String archiveStatus, - String archiverEndpoint, - String submissionBody) - throws JsonProcessingException, InterruptedException { - paramableAAChannelProcessorTest( - mockArchiverAppliance, - objectMapper, - aaChannelProcessor, - List.of(channel), - archiveStatus, - archiverEndpoint, - submissionBody); - } + @ParameterizedTest + @MethodSource("processNoPauseSource") + void testProcessNotArchivedActive( + Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) + throws JsonProcessingException, InterruptedException { + paramableAAChannelProcessorTest( + mockArchiverAppliance, + objectMapper, + aaChannelProcessor, + List.of(channel), + archiveStatus, + archiverEndpoint, + submissionBody); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorStatusPauseIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorStatusPauseIT.java index 2168d1ca..3a7c0302 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorStatusPauseIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorStatusPauseIT.java @@ -1,7 +1,14 @@ package org.phoebus.channelfinder.processors; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -14,70 +21,57 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; - @WebMvcTest(AAChannelProcessor.class) -@TestPropertySource(locations = "classpath:application_test.properties", properties = "aa.auto_pause=pvStatus") +@TestPropertySource( + locations = "classpath:application_test.properties", + properties = "aa.auto_pause=pvStatus") class AAChannelProcessorStatusPauseIT { - @Autowired - AAChannelProcessor aaChannelProcessor; + @Autowired AAChannelProcessor aaChannelProcessor; - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; - private static Stream processNoPauseSource() { + private static Stream processNoPauseSource() { - return Stream.of( - Arguments.of( - new Channel( - "PVArchivedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Being archived", - "pauseArchivingPV", - "[\"PVArchivedInactive\"]" - ), - Arguments.of( - new Channel("PVArchivedNotag", "owner", List.of(), List.of()), - "", - "", - "" - )); - } + return Stream.of( + Arguments.of( + new Channel( + "PVArchivedInactive", + "owner", + List.of(archiveProperty, inactiveProperty), + List.of()), + "Being archived", + "pauseArchivingPV", + "[\"PVArchivedInactive\"]"), + Arguments.of(new Channel("PVArchivedNotag", "owner", List.of(), List.of()), "", "", "")); + } - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); - objectMapper = new ObjectMapper(); - } + objectMapper = new ObjectMapper(); + } - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); - } + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } - @ParameterizedTest - @MethodSource("processNoPauseSource") - void testProcessNotArchivedActive( - Channel channel, - String archiveStatus, - String archiverEndpoint, - String submissionBody) - throws JsonProcessingException, InterruptedException { - paramableAAChannelProcessorTest( - mockArchiverAppliance, - objectMapper, - aaChannelProcessor, - List.of(channel), - archiveStatus, - archiverEndpoint, - submissionBody); - } + @ParameterizedTest + @MethodSource("processNoPauseSource") + void testProcessNotArchivedActive( + Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) + throws JsonProcessingException, InterruptedException { + paramableAAChannelProcessorTest( + mockArchiverAppliance, + objectMapper, + aaChannelProcessor, + List.of(channel), + archiveStatus, + archiverEndpoint, + submissionBody); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTagPauseIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTagPauseIT.java index e5dc9a79..8e89d4a3 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTagPauseIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTagPauseIT.java @@ -1,7 +1,14 @@ package org.phoebus.channelfinder.processors; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.stream.Stream; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -14,70 +21,61 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.TestPropertySource; -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; -import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.paramableAAChannelProcessorTest; - @WebMvcTest(AAChannelProcessor.class) -@TestPropertySource(locations = "classpath:application_test.properties", properties = "aa.auto_pause=archive") +@TestPropertySource( + locations = "classpath:application_test.properties", + properties = "aa.auto_pause=archive") class AAChannelProcessorTagPauseIT { - @Autowired - AAChannelProcessor aaChannelProcessor; + @Autowired AAChannelProcessor aaChannelProcessor; - MockWebServer mockArchiverAppliance; - ObjectMapper objectMapper; + MockWebServer mockArchiverAppliance; + ObjectMapper objectMapper; - private static Stream processNoPauseSource() { + private static Stream processNoPauseSource() { - return Stream.of( - Arguments.of( - new Channel( - "PVArchivedInactive", "owner", List.of(archiveProperty, inactiveProperty), List.of()), - "Being archived", - "", - ""), - Arguments.of( - new Channel("PVArchivedNotag", "owner", List.of(), List.of()), - "Being archived", - "pauseArchivingPV", - "[\"PVArchivedNotag\"]") - ); - } + return Stream.of( + Arguments.of( + new Channel( + "PVArchivedInactive", + "owner", + List.of(archiveProperty, inactiveProperty), + List.of()), + "Being archived", + "", + ""), + Arguments.of( + new Channel("PVArchivedNotag", "owner", List.of(), List.of()), + "Being archived", + "pauseArchivingPV", + "[\"PVArchivedNotag\"]")); + } - @BeforeEach - void setUp() throws IOException { - mockArchiverAppliance = new MockWebServer(); - mockArchiverAppliance.start(17665); + @BeforeEach + void setUp() throws IOException { + mockArchiverAppliance = new MockWebServer(); + mockArchiverAppliance.start(17665); - objectMapper = new ObjectMapper(); - } + objectMapper = new ObjectMapper(); + } - @AfterEach - void teardown() throws IOException { - mockArchiverAppliance.shutdown(); - } + @AfterEach + void teardown() throws IOException { + mockArchiverAppliance.shutdown(); + } - @ParameterizedTest - @MethodSource("processNoPauseSource") - void testProcessNotArchivedActive( - Channel channel, - String archiveStatus, - String archiverEndpoint, - String submissionBody) - throws JsonProcessingException, InterruptedException { - paramableAAChannelProcessorTest( - mockArchiverAppliance, - objectMapper, - aaChannelProcessor, - List.of(channel), - archiveStatus, - archiverEndpoint, - submissionBody - ); - } + @ParameterizedTest + @MethodSource("processNoPauseSource") + void testProcessNotArchivedActive( + Channel channel, String archiveStatus, String archiverEndpoint, String submissionBody) + throws JsonProcessingException, InterruptedException { + paramableAAChannelProcessorTest( + mockArchiverAppliance, + objectMapper, + aaChannelProcessor, + List.of(channel), + archiveStatus, + archiverEndpoint, + submissionBody); + } } diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTest.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTest.java index 5403c477..bcc19102 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTest.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorTest.java @@ -2,149 +2,148 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Stream; - import org.phoebus.channelfinder.processors.aa.ArchivePVOptions; class AAChannelProcessorTest { - @Test - void archivePropertyParsePass() { - ArchivePVOptions ar = new ArchivePVOptions(); - List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); - ar.setPv("sim://testing"); - ar.setSamplingParameters("monitor@1.0", testPolicyList); - - Assertions.assertEquals(ar.getPv(), "sim://testing"); - Assertions.assertEquals(ar.getSamplingMethod(), "MONITOR"); - Assertions.assertEquals(ar.getSamplingPeriod(), "1.0"); - - } - - @ParameterizedTest - @MethodSource("provideArchivePropertyArguments") - void testArchiveProperty(String parameters, List policyList, - String expectedSamplingMethod, String expectedSamplingPeriod) { - ArchivePVOptions ar = new ArchivePVOptions(); - ar.setSamplingParameters(parameters, policyList); - Assertions.assertEquals(expectedSamplingMethod, ar.getSamplingMethod()); - Assertions.assertEquals(expectedSamplingPeriod, ar.getSamplingPeriod()); - } - - private static Stream provideArchivePropertyArguments() { - List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); - return Stream.of( - // Failure - Arguments.of("@blah", testPolicyList, null, null), - Arguments.of("MONITOR@NOTNUMBER", testPolicyList, null, null), - Arguments.of("SCAN@1invalid", testPolicyList, null, null), - Arguments.of("SCAN@ 1.0", testPolicyList, null, null), - Arguments.of("SCAN @1", testPolicyList, null, null), - Arguments.of("INVALID@1", testPolicyList, null, null), - Arguments.of("@1.0", testPolicyList, null, null), - Arguments.of("oops@", testPolicyList, null, null), - Arguments.of("INVALID", testPolicyList, null, null), - Arguments.of("MMMONITOR@10.0", testPolicyList, null, null), - // Success - Arguments.of("MONITOR@0.01 ignore me", testPolicyList, "MONITOR", "0.01"), - Arguments.of("MONITOR@1 ignore me", testPolicyList, "MONITOR", "1"), - Arguments.of("MONITOR@0.01 ignore me", testPolicyList, "MONITOR", "0.01"), - Arguments.of("ScAn@10.01000", testPolicyList, "SCAN", "10.01000"), - Arguments.of("MONITOR@0.01", testPolicyList, "MONITOR", "0.01"), - Arguments.of("MONITOR@1", testPolicyList, "MONITOR", "1"), - Arguments.of("scan@.01", testPolicyList, "SCAN", ".01"), - Arguments.of("scan@1.01", testPolicyList, "SCAN", "1.01") - ); - } - - @Test - void defaultArchiveTag() { - ArchivePVOptions ar = new ArchivePVOptions(); - List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); - ar.setPv("sim://testing"); - ar.setSamplingParameters("default", testPolicyList); - - Assertions.assertEquals(ar.getPv(), "sim://testing"); - Assertions.assertNull(ar.getSamplingMethod()); - Assertions.assertNull(ar.getSamplingPeriod()); - Assertions.assertNull(ar.getPolicy()); - } - - @Test - void archivePolicyParsing() { - ArchivePVOptions ar = new ArchivePVOptions(); - ar.setPv("sim://testingPolicy"); - ar.setPolicy("Fast"); - - Assertions.assertEquals(ar.getPv(), "sim://testingPolicy"); - Assertions.assertNull(ar.getSamplingMethod()); - Assertions.assertNull(ar.getSamplingPeriod()); - Assertions.assertEquals(ar.getPolicy(), "Fast"); - - ar.setPolicy("SlowControlled"); - Assertions.assertNull(ar.getSamplingMethod()); - Assertions.assertNull(ar.getSamplingPeriod()); - Assertions.assertEquals(ar.getPolicy(), "SlowControlled"); - - ar.setSamplingParameters("scan@60", new ArrayList<>()); - Assertions.assertEquals(ar.getSamplingMethod(), "SCAN"); - Assertions.assertEquals(ar.getSamplingPeriod(), "60"); - Assertions.assertEquals(ar.getPolicy(), "SlowControlled"); - } - - @Test - void archivePVJson() throws JsonProcessingException { - ArchivePVOptions ar1 = new ArchivePVOptions(); - ar1.setPv("sim://testing1"); - ar1.setSamplingParameters("monitor@1.0", new ArrayList<>()); - - ArchivePVOptions ar2 = new ArchivePVOptions(); - ar2.setPv("sim://testing2"); - ar2.setSamplingParameters("scan@0.2", new ArrayList<>()); - - ObjectMapper objectMapper = new ObjectMapper(); - String str = objectMapper.writeValueAsString(List.of(ar1, ar2)); - - String expectedString = "[{\"pv\":\"sim://testing1\",\"samplingmethod\":\"MONITOR\",\"samplingperiod\":\"1.0\"},{\"pv\":\"sim://testing2\",\"samplingmethod\":\"SCAN\",\"samplingperiod\":\"0.2\"}]"; - Assertions.assertEquals(str, expectedString); - - // Only a pv name - ArchivePVOptions ar3 = new ArchivePVOptions(); - ar3.setPv("sim://testing3"); - str = objectMapper.writeValueAsString(List.of(ar3)); - - expectedString = "[{\"pv\":\"sim://testing3\"}]"; - Assertions.assertEquals(str, expectedString); - - // Test policies - List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); - - // Valid policy - ArchivePVOptions ar4 = new ArchivePVOptions(); - ar4.setPv("sim://testing4"); - ar4.setSamplingParameters("Fast", testPolicyList); - str = objectMapper.writeValueAsString(List.of(ar4)); - - expectedString = "[{\"pv\":\"sim://testing4\",\"policy\":\"Fast\"}]"; - Assertions.assertEquals(str, expectedString); - - // Invalid policy - ArchivePVOptions ar5 = new ArchivePVOptions(); - ar5.setPv("sim://testing5"); - ar5.setSamplingParameters("Fastest", testPolicyList); - str = objectMapper.writeValueAsString(List.of(ar5)); - - expectedString = "[{\"pv\":\"sim://testing5\"}]"; - Assertions.assertEquals(str, expectedString); - } - -} \ No newline at end of file + @Test + void archivePropertyParsePass() { + ArchivePVOptions ar = new ArchivePVOptions(); + List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); + ar.setPv("sim://testing"); + ar.setSamplingParameters("monitor@1.0", testPolicyList); + + Assertions.assertEquals(ar.getPv(), "sim://testing"); + Assertions.assertEquals(ar.getSamplingMethod(), "MONITOR"); + Assertions.assertEquals(ar.getSamplingPeriod(), "1.0"); + } + + @ParameterizedTest + @MethodSource("provideArchivePropertyArguments") + void testArchiveProperty( + String parameters, + List policyList, + String expectedSamplingMethod, + String expectedSamplingPeriod) { + ArchivePVOptions ar = new ArchivePVOptions(); + ar.setSamplingParameters(parameters, policyList); + Assertions.assertEquals(expectedSamplingMethod, ar.getSamplingMethod()); + Assertions.assertEquals(expectedSamplingPeriod, ar.getSamplingPeriod()); + } + + private static Stream provideArchivePropertyArguments() { + List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); + return Stream.of( + // Failure + Arguments.of("@blah", testPolicyList, null, null), + Arguments.of("MONITOR@NOTNUMBER", testPolicyList, null, null), + Arguments.of("SCAN@1invalid", testPolicyList, null, null), + Arguments.of("SCAN@ 1.0", testPolicyList, null, null), + Arguments.of("SCAN @1", testPolicyList, null, null), + Arguments.of("INVALID@1", testPolicyList, null, null), + Arguments.of("@1.0", testPolicyList, null, null), + Arguments.of("oops@", testPolicyList, null, null), + Arguments.of("INVALID", testPolicyList, null, null), + Arguments.of("MMMONITOR@10.0", testPolicyList, null, null), + // Success + Arguments.of("MONITOR@0.01 ignore me", testPolicyList, "MONITOR", "0.01"), + Arguments.of("MONITOR@1 ignore me", testPolicyList, "MONITOR", "1"), + Arguments.of("MONITOR@0.01 ignore me", testPolicyList, "MONITOR", "0.01"), + Arguments.of("ScAn@10.01000", testPolicyList, "SCAN", "10.01000"), + Arguments.of("MONITOR@0.01", testPolicyList, "MONITOR", "0.01"), + Arguments.of("MONITOR@1", testPolicyList, "MONITOR", "1"), + Arguments.of("scan@.01", testPolicyList, "SCAN", ".01"), + Arguments.of("scan@1.01", testPolicyList, "SCAN", "1.01")); + } + + @Test + void defaultArchiveTag() { + ArchivePVOptions ar = new ArchivePVOptions(); + List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); + ar.setPv("sim://testing"); + ar.setSamplingParameters("default", testPolicyList); + + Assertions.assertEquals(ar.getPv(), "sim://testing"); + Assertions.assertNull(ar.getSamplingMethod()); + Assertions.assertNull(ar.getSamplingPeriod()); + Assertions.assertNull(ar.getPolicy()); + } + + @Test + void archivePolicyParsing() { + ArchivePVOptions ar = new ArchivePVOptions(); + ar.setPv("sim://testingPolicy"); + ar.setPolicy("Fast"); + + Assertions.assertEquals(ar.getPv(), "sim://testingPolicy"); + Assertions.assertNull(ar.getSamplingMethod()); + Assertions.assertNull(ar.getSamplingPeriod()); + Assertions.assertEquals(ar.getPolicy(), "Fast"); + + ar.setPolicy("SlowControlled"); + Assertions.assertNull(ar.getSamplingMethod()); + Assertions.assertNull(ar.getSamplingPeriod()); + Assertions.assertEquals(ar.getPolicy(), "SlowControlled"); + + ar.setSamplingParameters("scan@60", new ArrayList<>()); + Assertions.assertEquals(ar.getSamplingMethod(), "SCAN"); + Assertions.assertEquals(ar.getSamplingPeriod(), "60"); + Assertions.assertEquals(ar.getPolicy(), "SlowControlled"); + } + + @Test + void archivePVJson() throws JsonProcessingException { + ArchivePVOptions ar1 = new ArchivePVOptions(); + ar1.setPv("sim://testing1"); + ar1.setSamplingParameters("monitor@1.0", new ArrayList<>()); + + ArchivePVOptions ar2 = new ArchivePVOptions(); + ar2.setPv("sim://testing2"); + ar2.setSamplingParameters("scan@0.2", new ArrayList<>()); + + ObjectMapper objectMapper = new ObjectMapper(); + String str = objectMapper.writeValueAsString(List.of(ar1, ar2)); + + String expectedString = + "[{\"pv\":\"sim://testing1\",\"samplingmethod\":\"MONITOR\",\"samplingperiod\":\"1.0\"},{\"pv\":\"sim://testing2\",\"samplingmethod\":\"SCAN\",\"samplingperiod\":\"0.2\"}]"; + Assertions.assertEquals(str, expectedString); + + // Only a pv name + ArchivePVOptions ar3 = new ArchivePVOptions(); + ar3.setPv("sim://testing3"); + str = objectMapper.writeValueAsString(List.of(ar3)); + + expectedString = "[{\"pv\":\"sim://testing3\"}]"; + Assertions.assertEquals(str, expectedString); + + // Test policies + List testPolicyList = Arrays.asList("Fast", "FastControlled", "Slow", "SlowControlled"); + + // Valid policy + ArchivePVOptions ar4 = new ArchivePVOptions(); + ar4.setPv("sim://testing4"); + ar4.setSamplingParameters("Fast", testPolicyList); + str = objectMapper.writeValueAsString(List.of(ar4)); + + expectedString = "[{\"pv\":\"sim://testing4\",\"policy\":\"Fast\"}]"; + Assertions.assertEquals(str, expectedString); + + // Invalid policy + ArchivePVOptions ar5 = new ArchivePVOptions(); + ar5.setPv("sim://testing5"); + ar5.setSamplingParameters("Fastest", testPolicyList); + str = objectMapper.writeValueAsString(List.of(ar5)); + + expectedString = "[{\"pv\":\"sim://testing5\"}]"; + Assertions.assertEquals(str, expectedString); + } +}