Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:mbussolotto:branches:systemsmanagement:Uyuni:Master
uyuni-java-common
uyuni-java-common-git-0.3b5a913.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File uyuni-java-common-git-0.3b5a913.obscpio of Package uyuni-java-common
07070100000000000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000001200000000uyuni-java-common07070100000001000081A4000003E80000006400000001662798DF000046AC000000000000000000000000000000000000001A00000000uyuni-java-common/LICENSE GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. 07070100000002000081A4000003E80000006400000001662798DF000007F8000000000000000000000000000000000000001A00000000uyuni-java-common/pom.xml<?xml version="1.0" encoding="UTF-8"?> <!-- ~ Copyright (c) 2024 SUSE LLC ~ ~ This software is licensed to you under the GNU General Public License, ~ version 2 (GPLv2). There is NO WARRANTY for this software, express or ~ implied, including the implied warranties of MERCHANTABILITY or FITNESS ~ FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 ~ along with this software; if not, see ~ http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. ~ ~ Red Hat trademarks are not licensed under GPLv2. No permission is ~ granted to use or replicate Red Hat trademarks that are incorporated ~ in this software or its documentation. --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.uyuni-project</groupId> <artifactId>uyuni-java-parent</artifactId> <version>5.0.3</version> <relativePath>../uyuni-java-parent</relativePath> </parent> <artifactId>uyuni-java-common</artifactId> <version>5.0.3</version> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> </dependencies> </project> 07070100000003000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000001600000000uyuni-java-common/src07070100000004000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000001B00000000uyuni-java-common/src/main07070100000005000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002000000000uyuni-java-common/src/main/java07070100000006000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002400000000uyuni-java-common/src/main/java/com07070100000007000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002900000000uyuni-java-common/src/main/java/com/suse07070100000008000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003000000000uyuni-java-common/src/main/java/com/suse/common07070100000009000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003B00000000uyuni-java-common/src/main/java/com/suse/common/concurrent0707010000000A000081A4000003E80000006400000001662798DF000010F4000000000000000000000000000000000000006300000000uyuni-java-common/src/main/java/com/suse/common/concurrent/UnboundedGrowingThreadPoolExecutor.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.concurrent; import java.time.Duration; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * A {@link ThreadPoolExecutor} that increases the threads in the pool even if the queue is not full. */ public class UnboundedGrowingThreadPoolExecutor extends ThreadPoolExecutor { private static final AtomicInteger CURRENT_ID = new AtomicInteger(1); private final PutBackExecutionHandler handler; /** * Default constructor * @param corePoolSize the number of core threads * @param maximumPoolSize the maximum number of threads to allow in the pool * @param keepAlive when the number of threads is greater than the core, this is the maximum time that excess * idle * threads will wait for new tasks before terminating. * @param threadNamePrefix the prefix to use for the name of the threads part of the pool */ public UnboundedGrowingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, Duration keepAlive, String threadNamePrefix) { super(corePoolSize, maximumPoolSize, keepAlive.getSeconds(), TimeUnit.SECONDS, new TransferOnOfferBlockingQueue()); handler = new PutBackExecutionHandler(); super.setRejectedExecutionHandler(handler); super.setThreadFactory(runnable -> new Thread(runnable, threadNamePrefix + "-" + CURRENT_ID.incrementAndGet())); super.prestartAllCoreThreads(); } @Override public void setRejectedExecutionHandler(RejectedExecutionHandler handlerIn) { handler.setExternalHandler(handlerIn); } /** * A blocking queue implementation that always tries to transfer the items offered */ private static class TransferOnOfferBlockingQueue extends LinkedTransferQueue<Runnable> { @Override public boolean offer(Runnable runnable) { // Try to transfer immediately the element to a consumer. If no consumers are available, reject the offer. // This will trigger the increase of the consumers pool return super.tryTransfer(runnable); } } /** * Custom handler of the rejection event to make sure the rejected item are put back to the queue */ private static class PutBackExecutionHandler implements RejectedExecutionHandler { private RejectedExecutionHandler externalHandler; @Override public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) { try { // This does the actual put into the queue. // Once the max threads have been reached, the tasks will then queue up. executor.getQueue().put(runnable); // we do this after the put() to stop race conditions if (executor.isShutdown()) { if (externalHandler == null) { throw new RejectedExecutionException("Task " + runnable + " rejected from " + executor); } else { externalHandler.rejectedExecution(runnable, executor); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public void setExternalHandler(RejectedExecutionHandler externalHandlerIn) { this.externalHandler = externalHandlerIn; } } } 0707010000000B000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003E00000000uyuni-java-common/src/main/java/com/suse/common/configuration0707010000000C000081A4000003E80000006400000001662798DF00000EAE000000000000000000000000000000000000005B00000000uyuni-java-common/src/main/java/com/suse/common/configuration/BaseConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; public abstract class BaseConfigurationSource implements ConfigurationSource { private static final List<String> TRUE_VALUES = List.of("1", "y", "true", "yes", "on"); @Override public Optional<String> getString(String property) { return Optional.ofNullable(getRawValue(property)) .map(String::trim) .filter(value -> !value.isEmpty()); } @Override public Optional<Integer> getInteger(String property) { return getString(property).map(value -> convertTo(value, Integer.class)); } @Override public Optional<Long> getLong(String property) { return getString(property).map(value -> convertTo(value, Long.class)); } @Override public Optional<Float> getFloat(String property) { return getString(property).map(value -> convertTo(value, Float.class)); } @Override public Optional<Double> getDouble(String property) { return getString(property).map(value -> convertTo(value, Double.class)); } @Override public Optional<Boolean> getBoolean(String property) { return getString(property).map(value -> convertTo(value, Boolean.class)); } @Override public <T> Optional<List<T>> getList(String property, Class<T> itemClass) { return getString(property) .stream() .flatMap(value -> Arrays.stream(value.split(","))) .map(item -> convertTo(item, itemClass)) .collect(Collectors.collectingAndThen(Collectors.toList(), Optional::of)) .filter(values -> !values.isEmpty()); } @Override public Properties toProperties() { Set<String> propertyNames = getPropertyNames(); Properties properties = new Properties(propertyNames.size()); propertyNames.forEach(property -> { properties.put(property, getRawValue(property)); }); return properties; } protected abstract String getRawValue(String property); protected <T> T convertTo(String value, Class<T> valueClass) { Object convertedValue; if (valueClass.equals(String.class)) { convertedValue = value; } else if (valueClass.equals(Integer.class)) { convertedValue = Integer.valueOf(value); } else if (valueClass.equals(Long.class)) { convertedValue = Long.valueOf(value); } else if (valueClass.equals(Float.class)) { convertedValue = Float.valueOf(value); } else if (valueClass.equals(Double.class)) { convertedValue = Double.valueOf(value); } else if (valueClass.equals(Boolean.class)) { convertedValue = TRUE_VALUES.contains(value.toLowerCase()); } else { throw new IllegalStateException("Unsupported class type " + valueClass.getName()); } return valueClass.cast(convertedValue); } } 0707010000000D000081A4000003E80000006400000001662798DF00000AD1000000000000000000000000000000000000005700000000uyuni-java-common/src/main/java/com/suse/common/configuration/ConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import java.util.List; import java.util.Optional; import java.util.Properties; import java.util.Set; public interface ConfigurationSource { /** * Retrieve the boolean value of a property. * @param property the property name * @return the boolean wrapped into an {@link Optional} */ Optional<Boolean> getBoolean(String property); /** * Retrieve the string value of a property. * @param property the property name * @return the string wrapped into an {@link Optional} */ Optional<String> getString(String property); /** * Retrieve the integer value of a property. * @param property the property name * @return the integer wrapped into an {@link Optional} */ Optional<Integer> getInteger(String property); /** * Retrieve the long value of a property. * @param property the property name * @return the long wrapped into an {@link Optional} */ Optional<Long> getLong(String property); /** * Retrieve the float value of a property. * @param property the property name * @return the float wrapped into an {@link Optional} */ Optional<Float> getFloat(String property); /** * Retrieve the double value of a property. * @param property the property name * @return the double wrapped into an {@link Optional} */ Optional<Double> getDouble(String property); /** * Retrieve the list value of a property. * @param property the property name * @param itemClass the type of item of the list. * @return the list wrapped into an {@link Optional} * @param <T> the type of item of the list */ <T> Optional<List<T>> getList(String property, Class<T> itemClass); /** * Retrieves the names of all the available properties. * @return the set of property names */ Set<String> getPropertyNames(); /** * Converts this configuration source to a {@link Properties} object. * @return all the properties value stored into {@link Properties} object */ Properties toProperties(); } 0707010000000E000081A4000003E80000006400000001662798DF00000474000000000000000000000000000000000000006200000000uyuni-java-common/src/main/java/com/suse/common/configuration/EnvironmentConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import java.util.Collections; import java.util.Set; /** * A configuration source that's retrieving the property values from the system environment. */ public class EnvironmentConfigurationSource extends BaseConfigurationSource { @Override protected String getRawValue(String property) { return System.getenv(property); } @Override public Set<String> getPropertyNames() { return Collections.unmodifiableSet(System.getenv().keySet()); } } 0707010000000F000081A4000003E80000006400000001662798DF00001E2D000000000000000000000000000000000000005B00000000uyuni-java-common/src/main/java/com/suse/common/configuration/FileConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; public class FileConfigurationSource extends BaseConfigurationSource { // This comparator is needed to make sure we read the child namespace before the base namespace. // We sort the item in reverse order based on the length of the file name. If two filenames have the same length, // then we need to do a lexicographical comparison to make sure that the filenames themselves are different. private static final Comparator<Path> CONFIG_PATH_COMPARATOR = (p1, p2) -> { int lenDif = p2.toAbsolutePath().toString().length() - p1.toAbsolutePath().toString().length(); return lenDif != 0 ? lenDif : p2.compareTo(p1); }; private static final Logger LOGGER = LogManager.getLogger(FileConfigurationSource.class); private final List<String> fallbackNamespaces; private final String commonFilePrefix; private final Properties configValues; /** * Builds a file configuration source. * @param fileSourcesIn List of files and directories to process */ public FileConfigurationSource(List<Path> fileSourcesIn) { this(fileSourcesIn, null, Collections.emptyList()); } /** * Builds a file configuration source. * @param fileSourcesIn List of files and directories to process * @param filePrefixIn a common prefix used by all configuration file names */ public FileConfigurationSource(List<Path> fileSourcesIn, String filePrefixIn) { this(fileSourcesIn, filePrefixIn, Collections.emptyList()); } /** * Builds a file configuration source. * @param fileSourcesIn List of files and directories to process * @param filePrefixIn a common prefix used by all configuration file names * @param fallbackNamespacesIn namespaces to search for, in the given order. These are used when a property, * specified with no namespace, was not found. */ public FileConfigurationSource(List<Path> fileSourcesIn, String filePrefixIn, List<String> fallbackNamespacesIn) { configValues = new Properties(); commonFilePrefix = filePrefixIn; fallbackNamespaces = fallbackNamespacesIn; fileSourcesIn.stream() .flatMap(path -> getConfigurationFiles(path)) .sorted(CONFIG_PATH_COMPARATOR) .map(file -> loadProperties(file)) .forEach(props -> configValues.putAll(props)); } /** * Get the configuration entry for given property * * @param property string to get the value of * @return the value */ @Override protected String getRawValue(String property) { LOGGER.debug("getString() - called with: {}", property); if (property == null) { return null; } String namespace = ""; String propertyName = property; int lastDot = property.lastIndexOf('.'); if (lastDot > 0) { propertyName = property.substring(lastDot + 1); namespace = property.substring(0, lastDot); } LOGGER.debug("getString() - Getting property: {}", propertyName); String result = configValues.getProperty(propertyName); LOGGER.debug("getString() result: {}", result); if (result == null) { if (!namespace.isEmpty()) { result = configValues.getProperty(namespace + "." + propertyName); } else { // The property was not found, and it has no namespace. Lookup all the provided fallback namespaces for (String fallback : fallbackNamespaces) { result = configValues.getProperty(fallback + "." + propertyName); if (result != null) { break; } } } } LOGGER.debug("getString() - returning: {}", result); if (result == null || result.isEmpty()) { return null; } return result.trim(); } @Override public Set<String> getPropertyNames() { return configValues.keySet().stream() .map(Objects::toString) .collect(Collectors.toUnmodifiableSet()); } private static Stream<Path> getConfigurationFiles(Path path) { if (Files.isDirectory(path)) { try { return Files.list(path) .filter(file -> file.getFileName().toString().endsWith(".conf")); } catch (IOException ex) { LOGGER.error("Unable to list file in directory {}", path); return Stream.empty(); } } return Stream.of(path); } private Properties loadProperties(Path file) { Properties properties; try { String fileContent = Files.readString(file, StandardCharsets.UTF_8); properties = new Properties(); properties.load(new StringReader(fileContent.replace("\\", "\\\\"))); } catch (Exception ex) { LOGGER.error("Could not parse file {}", file, ex); return new Properties(); } String namespace = makeNamespace(file); LOGGER.debug("Adding namespace: {} for file: {}", namespace, file.toAbsolutePath()); for (Object key : properties.keySet()) { String propertyName = (String) key; if (!propertyName.startsWith(namespace)) { String qualifiedProperty = namespace + "." + propertyName; Object value = properties.remove(propertyName); LOGGER.debug("Adding: {}: {}", qualifiedProperty, value); properties.put(qualifiedProperty, value); } } return properties; } private String makeNamespace(Path path) { String namespace = path.getFileName().toString(); // If a common filename prefix was specified if (commonFilePrefix != null) { // This is really hokey, but it works. Basically, rhn.conf doesn't // match the standard rhn_foo.conf convention. So, to create the // namespace, we first special case rhn.* if (namespace.startsWith(commonFilePrefix + ".")) { return ""; } namespace = namespace.replaceFirst(commonFilePrefix + "_", ""); } int lastDotindex = namespace.lastIndexOf('.'); if (lastDotindex != -1) { namespace = namespace.substring(0, namespace.lastIndexOf('.')); } namespace = namespace.replace("_", "."); return namespace; } } 07070100000010000081A4000003E80000006400000001662798DF00000F2B000000000000000000000000000000000000005F00000000uyuni-java-common/src/main/java/com/suse/common/configuration/MultipleConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class MultipleConfigurationSource implements ConfigurationSource { // Using a deque since we need to traverse it in both directions private final Deque<ConfigurationSource> configurationSources; /** * Build a combined configuration source from the combination of all the ones specified in the list. * @param configurationSourcesIn the list of sources. The order of the sources will be respected when retrieving * the properties. */ public MultipleConfigurationSource(List<ConfigurationSource> configurationSourcesIn) { this.configurationSources = new LinkedList<>(configurationSourcesIn); } @Override public Optional<Boolean> getBoolean(String property) { return getFirstValue(property, ConfigurationSource::getBoolean); } @Override public Optional<String> getString(String property) { return getFirstValue(property, ConfigurationSource::getString); } @Override public Optional<Integer> getInteger(String property) { return getFirstValue(property, ConfigurationSource::getInteger); } @Override public Optional<Long> getLong(String property) { return getFirstValue(property, ConfigurationSource::getLong); } @Override public Optional<Float> getFloat(String property) { return getFirstValue(property, ConfigurationSource::getFloat); } @Override public Optional<Double> getDouble(String property) { return getFirstValue(property, ConfigurationSource::getDouble); } @Override public <T> Optional<List<T>> getList(String property, Class<T> itemClass) { return configurationSources.stream() .flatMap(source -> source.getList(property, itemClass).stream()) .findFirst(); } private <T> Optional<T> getFirstValue(String property, BiFunction<ConfigurationSource, String, Optional<T>> propertyRetriever) { return configurationSources.stream() .flatMap(source -> propertyRetriever.apply(source, property).stream()) .findFirst(); } @Override public Set<String> getPropertyNames() { // The set of property names won't be ordered return configurationSources.stream() .flatMap(source -> source.getPropertyNames().stream()) .collect(Collectors.toUnmodifiableSet()); } @Override public Properties toProperties() { Properties combineProperties = new Properties(); // Iterate the source in the opposite order, so the values from the firsts take precedence over the lasts Iterable<ConfigurationSource> sources = configurationSources::descendingIterator; StreamSupport.stream(sources.spliterator(), false) .map(source -> source.toProperties()) .forEach(properties -> combineProperties.putAll(properties)); return combineProperties; } } 07070100000011000081A4000003E80000006400000001662798DF00000819000000000000000000000000000000000000005F00000000uyuni-java-common/src/main/java/com/suse/common/configuration/ResourceConfigurationSource.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.InputStream; import java.util.Objects; import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; /** * A configuration source that's retrieving the values from a resource file */ public class ResourceConfigurationSource extends BaseConfigurationSource { private static final Logger LOGGER = LogManager.getLogger(ResourceConfigurationSource.class); private final Properties properties; /** * Default constructor * @param resourceName the name of the resource, usable by the system class loader to locate it. */ public ResourceConfigurationSource(String resourceName) { properties = new Properties(); try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(resourceName)) { properties.load(inputStream); } catch (Exception ex) { LOGGER.error("Unable to load configuration from resource {}", resourceName, ex); properties.clear(); } } @Override protected String getRawValue(String property) { return properties.getProperty(property); } @Override public Set<String> getPropertyNames() { return properties.keySet().stream() .map(Objects::toString) .collect(Collectors.toUnmodifiableSet()); } } 07070100000012000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003900000000uyuni-java-common/src/main/java/com/suse/common/database07070100000013000081A4000003E80000006400000001662798DF0000042C000000000000000000000000000000000000005400000000uyuni-java-common/src/main/java/com/suse/common/database/C3P0DataSourceFactory.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.database; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory; /** * Mybatis data source factory backed by a C3P0 Pooled Data source */ public class C3P0DataSourceFactory extends UnpooledDataSourceFactory { /** * Default constructor. */ public C3P0DataSourceFactory() { this.dataSource = new ComboPooledDataSource(); } } 07070100000014000081A4000003E80000006400000001662798DF000008BA000000000000000000000000000000000000005500000000uyuni-java-common/src/main/java/com/suse/common/database/DatabaseSessionFactory.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.database; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; import java.util.Properties; /** * A wrapper to initialize and store the Mybatis {@link SqlSessionFactory} */ public class DatabaseSessionFactory { private static SqlSessionFactory sessionFactory = null; private DatabaseSessionFactory() { // Prevent instantiation } /** * Initialize the database session * @param configResource the path of the configuration file, processable by an invocation of * {@link ClassLoader#getSystemResourceAsStream(String)} * @param properties runtime configuration properties to customize the configuration */ public static synchronized void initialize(String configResource, Properties properties) { try (InputStream stream = ClassLoader.getSystemResourceAsStream(configResource)) { sessionFactory = new SqlSessionFactoryBuilder().build(stream, properties); } catch (Exception ex) { throw new IllegalStateException("Unable to initialize database session factory", ex); } } /** * Check if the database session factory is initialized * @return true if the session factory has been initialized */ public static boolean isInitialized() { return sessionFactory != null; } /** * Get the database session factory * @return the static instance */ public static SqlSessionFactory getSessionFactory() { return sessionFactory; } } 07070100000015000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003300000000uyuni-java-common/src/main/java/com/suse/common/io07070100000016000081A4000003E80000006400000001662798DF000013D8000000000000000000000000000000000000004B00000000uyuni-java-common/src/main/java/com/suse/common/io/ByteSequenceFinder.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.io; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; /** * Finds a byte sequence in a stream of bytes. Uses the Knuth–Morris–Pratt search algorithm for better performance. * <p> * The algorithm remembers the past matched characters in order to avoid restarting from the beginning of the pattern * when a mismatch is found. This is obtained by building a lookup of a partial match table called failure function. * <p> * <a href="https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm">Algorithm reference</a>. */ public class ByteSequenceFinder { private byte[] sequence; private int[] failure; /** * Default constructor */ public ByteSequenceFinder() { this(new byte[0]); } /** * Create a new instance. * @param sequenceIn the sequence to find */ public ByteSequenceFinder(byte[] sequenceIn) { setSequence(sequenceIn); } /** * Finds the first occurrence of the pattern in the specified byte array. * @param bytes the byte array where the sequence is searched * @return the index where the sequence starts within the array, <code>-1</code> if the sequence was not found. * @throws IOException when an error processing the stream of bytes occurs */ public int search(byte[] bytes) throws IOException { return search(new ByteArrayInputStream(bytes)); } /** * Finds the first occurrence of the pattern in the specified stream. The stream will be consumed up to end * of the sequence matched. It will be fully consumed if no match is found. * @param stream the input stream to search * @return the position where the sequence starts within the stream and the stream will be positioned AFTER the * end of the sequence. Otherwise, <code>-1</code> if the sequence was not found. * @throws IOException when an error processing the stream occurs */ public int search(InputStream stream) throws IOException { int data = stream.read(); // If the sequence is empty and the stream is empty as well, return that the sequence is found // This case is similar to "".indexOf("") and "".contains("") if (sequence.length == 0 && data == -1) { return 0; } int matchedLength = 0; int bytesRead = 1; while (data != -1) { // If the byte is correct if (sequence[matchedLength] == (byte) data) { // Increment the length of current match matchedLength++; if (matchedLength == sequence.length) { // All sequence matched return bytesRead - sequence.length; } data = stream.read(); bytesRead++; } else { // Mismatch: check the failure function to see from where to restart matchedLength = failure[matchedLength]; // If we hit -1 there is no change for a partial match, we restart from zero and read the next byte if (matchedLength == -1) { matchedLength = 0; data = stream.read(); bytesRead++; } } } return -1; } /** * Retrieves the current sequence used by a search method. * @return the current sequence to be searched */ public byte[] getSequence() { return sequence; } /** * Sets the sequence to be used by the next invocation of a search method. * @param sequenceIn the new sequence to search */ public void setSequence(byte[] sequenceIn) { this.sequence = sequenceIn; this.failure = updateFailureFunction(sequence); } /** * Computes the failure function. Evaluates the sequence and find repeating prefixes. */ private static int[] updateFailureFunction(byte[] sequence) { int[] failure = new int[sequence.length + 1]; failure[0] = -1; int prefixLength = -1; int i = 0; while (i < sequence.length) { while (prefixLength >= 0 && sequence[prefixLength] != sequence[i]) { prefixLength = failure[prefixLength]; } failure[++i] = ++prefixLength; } return failure; } } 07070100000017000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000001B00000000uyuni-java-common/src/test07070100000018000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002000000000uyuni-java-common/src/test/java07070100000019000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002400000000uyuni-java-common/src/test/java/com0707010000001A000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002900000000uyuni-java-common/src/test/java/com/suse0707010000001B000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003000000000uyuni-java-common/src/test/java/com/suse/common0707010000001C000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003B00000000uyuni-java-common/src/test/java/com/suse/common/concurrent0707010000001D000081A4000003E80000006400000001662798DF00002136000000000000000000000000000000000000006700000000uyuni-java-common/src/test/java/com/suse/common/concurrent/UnboundedGrowingThreadPoolExecutorTest.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.concurrent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.AssertionsKt.fail; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.time.Duration; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.IntStream; @Disabled("These tests are flaky and fails when executed by GitHub actions") class UnboundedGrowingThreadPoolExecutorTest { public static final String THREAD_PREFIX = "unit-test"; private ExecutorService executorService; @AfterEach public void tearDown() { if (executorService == null) { return; } try { executorService.shutdownNow(); assertTrue(executorService.awaitTermination(5, TimeUnit.SECONDS), "Unable to terminate executor"); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); fail("Unexpected interruption while terminating executor", ex); } } @Test @DisplayName("Creates and start the correct number of core threads") void canCreateAndStartCoreThreads() { executorService = new UnboundedGrowingThreadPoolExecutor(2, 10, Duration.ofSeconds(1), THREAD_PREFIX); // Verify core threads are created assertEquals(2, getUnitThreads().size()); } @Test @DisplayName("Allows zero core threads") void canStartWithoutCoreThreads() { executorService = new UnboundedGrowingThreadPoolExecutor(0, 10, Duration.ofSeconds(1), THREAD_PREFIX); // Verify no core threads are created assertEquals(0, getUnitThreads().size()); } @Test @DisplayName("Can increase number of threads when tasks are added and close them when done") void canIncreaseNumberOfThreads() { executorService = new UnboundedGrowingThreadPoolExecutor(5, 10, Duration.ofMillis(500), THREAD_PREFIX); final CountDownLatch completeTaskLatch = new CountDownLatch(1); // Verify core threads are created assertEquals(5, getUnitThreads().size()); // start 3 tasks IntStream.range(0, 3).forEach(idx -> executorService.submit(new DummyTask(completeTaskLatch))); // Threads should remain the same assertEquals(5, getUnitThreads().size()); // start 5 more tasks IntStream.range(0, 5).forEach(idx -> executorService.submit(new DummyTask(completeTaskLatch))); // Threads should have increased assertEquals(8, getUnitThreads().size()); // Complete the tasks completeTaskLatch.countDown(); // Thread should still be the same number assertEquals(8, getUnitThreads().size()); sleep(Duration.ofSeconds(1)); // Non-core threads should be expired assertEquals(5, getUnitThreads().size()); sleep(Duration.ofSeconds(1)); // Non-core threads should not expire assertEquals(5, getUnitThreads().size()); } @Test @DisplayName("Does not create more threads than the specified max pool size") void cannotCreateMoreThreadThanGivenMaxPoolSize() { executorService = new UnboundedGrowingThreadPoolExecutor(1, 5, Duration.ofMillis(500), THREAD_PREFIX); final CountDownLatch phaseOneLatch = new CountDownLatch(1); final CountDownLatch phaseTwoLatch = new CountDownLatch(1); List<DummyTask> taskList = new LinkedList<>(); // Verify core threads are created assertEquals(1, getUnitThreads().size()); // start 3 tasks IntStream.range(0, 3).forEach(idx -> { DummyTask task = new DummyTask(phaseOneLatch); taskList.add(task); executorService.submit(task); }); // Threads should increase assertEquals(3, getUnitThreads().size()); // All tasks should be started assertTrue(taskList.stream().allMatch(task -> task.getStatus() == TaskStatus.RUNNING)); // start 2 more tasks IntStream.range(0, 2).forEach(idx -> { DummyTask task = new DummyTask(phaseOneLatch); taskList.add(task); executorService.submit(task); }); // Threads reach max pool size assertEquals(5, getUnitThreads().size()); // All tasks should be started assertTrue(taskList.stream().allMatch(task -> task.getStatus() == TaskStatus.RUNNING)); // start 3 more tasks IntStream.range(0, 3).forEach(idx -> { DummyTask task = new DummyTask(phaseTwoLatch); taskList.add(task); executorService.submit(task); }); // Threads should not exceed max pool size assertEquals(5, getUnitThreads().size()); // 5 tasks should be started, 3 should not assertEquals(5, taskList.stream().filter(task -> task.getStatus() == TaskStatus.RUNNING).count()); assertEquals(3, taskList.stream().filter(task -> task.getStatus() == TaskStatus.WAITING).count()); // Complete phase one and additional tasks should be picked up phaseOneLatch.countDown(); // We should still have a full pool of threads assertEquals(5, getUnitThreads().size()); // 5 tasks should be completed, 3 should be started assertEquals(5, taskList.stream().filter(task -> task.getStatus() == TaskStatus.COMPLETED).count()); assertEquals(3, taskList.stream().filter(task -> task.getStatus() == TaskStatus.RUNNING).count()); // Wait a bit sleep(Duration.ofSeconds(1)); // Two unused threads should be expired assertEquals(3, getUnitThreads().size()); // Complete the remaining tasks phaseTwoLatch.countDown(); // We should still have 3 threads assertEquals(3, getUnitThreads().size()); // All tasks should be completed assertEquals(8, taskList.stream().filter(task -> task.getStatus() == TaskStatus.COMPLETED).count()); // Wait a bit sleep(Duration.ofSeconds(1)); // Only one core thread should still be available assertEquals(1, getUnitThreads().size()); } private List<Thread> getUnitThreads() { return Thread.getAllStackTraces().keySet().stream() .filter(t -> t.getName().startsWith(THREAD_PREFIX)) .collect(Collectors.toList()); } private synchronized void sleep(Duration duration) { // Wait for the keep alive period to expire try { Thread.sleep(duration.toMillis()); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); fail("Unexpected interruption", ex); } } private enum TaskStatus { WAITING, RUNNING, COMPLETED } private static class DummyTask implements Runnable { private TaskStatus status; private final CountDownLatch terminateLatch; DummyTask(CountDownLatch terminateLatchIn) { this.terminateLatch = terminateLatchIn; this.status = TaskStatus.WAITING; } @Override public void run() { try { status = TaskStatus.RUNNING; terminateLatch.await(); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); fail("Unexpected interruption", ex); } status = TaskStatus.COMPLETED; } public TaskStatus getStatus() { return status; } } } 0707010000001E000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003E00000000uyuni-java-common/src/test/java/com/suse/common/configuration0707010000001F000081A4000003E80000006400000001662798DF00001AA7000000000000000000000000000000000000006300000000uyuni-java-common/src/test/java/com/suse/common/configuration/AbstractConfigurationSourceTest.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.List; import java.util.Optional; abstract class AbstractConfigurationSourceTest { protected ConfigurationSource source; @BeforeEach public void setup() throws Exception { source = createConfigurationSource(); } protected abstract ConfigurationSource createConfigurationSource() throws Exception ; @Nested @DisplayName("Basic retrieval") class BasicRetrievalTest { @Test @DisplayName("Value string should be retrieved") void testRetrieveValue() { assertOptionalEquals("value", source.getString("prefix.simple_value")); } @Test @DisplayName("Spaces should be trimmed") void testTrimSpaces() { assertOptionalEquals("all trailing spaces should be trimmed", source.getString("prefix.with_spaces")); } @Test @DisplayName("Empty definition should be treated as undefined property") void testDefaultValueQuoteQuote() { assertOptionalEmpty(source.getString("prefix.empty")); } } @Nested @DisplayName("List values") class ListTest { @Test @DisplayName("Retrieve list of one element") void testGetList1Elem() { assertOptionalEquals(List.of("some value"), source.getList("prefix.array_one_element", String.class)); } @Test @DisplayName("Retrieve comma separated value as list") void testGetStringArrayMultElem() { assertOptionalEquals(List.of("every", "good", "boy", "does", "fine"), source.getList("prefix.comma_separated", String.class)); } @Test @DisplayName("Item whitespace behaviour when retrieving list values") void testGetStringArrayWhitespace() { assertOptionalEquals(List.of("every", " good ", " boy ", " does", "fine"), source.getList("prefix.comma_no_trim", String.class)); } } @Nested @DisplayName("Conversion from string to specific type") class ConversionTest { @Test @DisplayName("Boolean values") public void testGetBoolean() { assertOptionalTrue(source.getBoolean("prefix.boolean_true")); assertOptionalFalse(source.getBoolean("prefix.boolean_false")); assertOptionalTrue(source.getBoolean("prefix.boolean_1")); assertOptionalFalse(source.getBoolean("prefix.boolean_0")); assertOptionalTrue(source.getBoolean("prefix.boolean_y")); assertOptionalTrue(source.getBoolean("prefix.boolean_Y")); assertOptionalFalse(source.getBoolean("prefix.boolean_n")); assertOptionalTrue(source.getBoolean("prefix.boolean_on")); assertOptionalFalse(source.getBoolean("prefix.boolean_off")); assertOptionalTrue(source.getBoolean("prefix.boolean_yes")); assertOptionalFalse(source.getBoolean("prefix.boolean_no")); assertOptionalFalse(source.getBoolean("prefix.boolean_foo")); assertOptionalFalse(source.getBoolean("prefix.boolean_10")); assertOptionalEmpty(source.getBoolean("prefix.boolean_empty")); assertOptionalEmpty(source.getBoolean("prefix.boolean_not_there")); assertOptionalTrue(source.getBoolean("prefix.boolean_on")); assertOptionalFalse(source.getBoolean("prefix.boolean_off")); } @Test @DisplayName("Integer values") void testGetInteger() { // lookup a non existent value assertOptionalEmpty(source.getInteger("value.doesnotexist")); // lookup an existing value assertOptionalEquals(100, source.getInteger("prefix.int_100")); assertOptionalEquals(-10, source.getInteger("prefix.int_minus10")); assertOptionalEquals(0, source.getInteger("prefix.int_zero")); assertOptionalEquals(100, source.getInteger("prefix.int_100")); Assertions.assertThrows(NumberFormatException.class, () -> source.getInteger("prefix.int_y")); } @Test @DisplayName("Double values") void testGetDouble() { assertOptionalEquals(10.0, source.getDouble("prefix.double")); } @Test @DisplayName("Float values") void testGetFloat() { assertOptionalEquals(10.0f, source.getFloat("prefix.float")); } } @Nested @DisplayName("Undefined properties") class UndefinedTest { @Test void testGetUndefinedInt() { assertOptionalEmpty(source.getInteger("Undefined_integer_variable")); } @Test void testGetUndefinedString() { assertOptionalEmpty(source.getString("Undefined_string_variable")); } @Test void testGetUndefinedBoolean() { assertOptionalEmpty(source.getBoolean("Undefined_boolean_variable")); } @Test @DisplayName("Retrieve undefined list") void testGetListNull() { assertOptionalEmpty(source.getList("Undefined_list_variable", String.class)); } } protected static <T> void assertOptionalEquals(T expected, Optional<T> actual) { assertEquals(expected, actual.orElseGet(() -> Assertions.fail("Optional has no value"))); } protected static <T> void assertOptionalEmpty(Optional<T> actual) { assertTrue(actual.isEmpty(), "Optional has a value"); } protected static void assertOptionalTrue(Optional<Boolean> actual) { assertTrue(actual.orElseGet(() -> Assertions.fail("Optional has no value"))); } protected static void assertOptionalFalse(Optional<Boolean> actual) { assertFalse(actual.orElseGet(() -> Assertions.fail("Optional has no value"))); } } 07070100000020000081A4000003E80000006400000001662798DF00000B08000000000000000000000000000000000000005F00000000uyuni-java-common/src/test/java/com/suse/common/configuration/BaseConfigurationSourceTest.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import java.util.Collections; import java.util.Map; import java.util.Set; class BaseConfigurationSourceTest extends AbstractConfigurationSourceTest { private Map<String, String> propertiesMap; protected ConfigurationSource createConfigurationSource() { propertiesMap = Map.ofEntries( Map.entry("prefix.simple_value", "value"), Map.entry("prefix.with_spaces", " all trailing spaces should be trimmed "), Map.entry("prefix.empty", ""), Map.entry("prefix.array_one_element", "some value"), Map.entry("prefix.comma_separated", "every,good,boy,does,fine"), Map.entry("prefix.comma_no_trim", "every, good , boy , does,fine"), Map.entry("prefix.boolean_true", "true"), Map.entry("prefix.boolean_false", "false"), Map.entry("prefix.boolean_1", "1"), Map.entry("prefix.boolean_0", "0"), Map.entry("prefix.boolean_y", "y"), Map.entry("prefix.boolean_Y", "Y"), Map.entry("prefix.boolean_n", "n"), Map.entry("prefix.boolean_yes", "yes"), Map.entry("prefix.boolean_no", "no"), Map.entry("prefix.boolean_foo", "foo"), Map.entry("prefix.boolean_10", "10"), Map.entry("prefix.boolean_empty", ""), Map.entry("prefix.boolean_on", "on"), Map.entry("prefix.boolean_off", "off"), Map.entry("prefix.int_minus10", "-10"), Map.entry("prefix.int_zero", "0"), Map.entry("prefix.int_100", "100"), Map.entry("prefix.int_y", "y"), Map.entry("prefix.double", "10.0"), Map.entry("prefix.float", "10.0") ); // Implement a configuration source backed by the map return new BaseConfigurationSource() { @Override protected String getRawValue(String property) { return propertiesMap.get(property); } @Override public Set<String> getPropertyNames() { return Collections.unmodifiableSet(propertiesMap.keySet()); } }; } } 07070100000021000081A4000003E80000006400000001662798DF00001D95000000000000000000000000000000000000005F00000000uyuni-java-common/src/test/java/com/suse/common/configuration/FileConfigurationSourceTest.java/* * Copyright (c) 2009--2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.configuration; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.List; class FileConfigurationSourceTest extends AbstractConfigurationSourceTest { private Path tempDirectory; protected ConfigurationSource createConfigurationSource() throws Exception { // create test config path tempDirectory = Files.createTempDirectory("ConfigTest-"); List<String> paths = List.of( "rhn.conf", "default/rhn_web.conf", "default/rhn_prefix.conf", "default/bug154517.conf.rpmsave" ); // copy test configuration files over for (String relativePath : paths) { InputStream inputStream = FileConfigurationSourceTest.class.getResourceAsStream(relativePath); if (inputStream == null) { throw new IllegalStateException("Unable to load resource " + relativePath); } Path targetPath = tempDirectory.resolve(Path.of(relativePath)); Files.createDirectories(targetPath.getParent()); Files.copy(inputStream, targetPath); } return new FileConfigurationSource( List.of(tempDirectory, tempDirectory.resolve("default")), "rhn", List.of("web", "server") ); } @AfterEach public void tearDown() throws IOException { // Delete test files Files.walk(tempDirectory) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); } @Nested @DisplayName("Namespaced retrieval") class NamespacedTest { @Test @DisplayName("Fully qualified in rhn_web.conf, accessed fully qualified") void testGetFullyQualified() { assertOptionalEquals("this is a property with a prefix", source.getString("web.property_with_prefix")); assertOptionalEquals("this is a property without a prefix", source.getString("web.without_prefix")); } @Test @DisplayName("Fully qualified in rhn_web.conf, accessed by name only") void testGetByPropertyNameOnly() { assertOptionalEquals("this is a property with a prefix", source.getString("property_with_prefix")); assertOptionalEquals("this is a property without a prefix", source.getString("without_prefix")); } @Test @DisplayName("Retrieve unprefixed property") void testUnprefixedProperty() { assertOptionalEquals("thirty-three", source.getString("prefix.foo")); assertOptionalEmpty(source.getString("foo")); } @Test @DisplayName("Ignore files without .conf extension") void testBug154517IgnoreRpmsave() { assertOptionalEmpty(source.getString("bug154517.conf.betternotfindme")); assertOptionalEmpty(source.getString("betternotfindme")); assertOptionalEmpty(source.getString("random.property_definition")); assertOptionalEmpty(source.getString("random.file.property_definition")); assertOptionalEmpty(source.getString("property_definition")); } } @Nested @DisplayName("Property override mechanism") class OvverideTest { @Test @DisplayName("Fully qualified in rhn_web.conf, overridden without prefix in rhn.conf, accessed fully qualified") void testOverride() { assertOptionalEquals("keep", source.getString("web.to_override")); } @Test @DisplayName("Fully qualified in rhn_web.conf, overridden without prefix in rhn.conf, accessed by name only") void testOverride1() { assertOptionalEquals("keep", source.getString("to_override")); } @Test @DisplayName("Fully qualified in rhn_web.conf, overridden fully qualified in rhn.conf, accessed fully qualified") void testOverride2() { assertOptionalEquals("1", source.getString("web.fq_to_override")); } @Test @DisplayName("Fully qualified in rhn_web.conf, overridden fully qualified in rhn.conf, accessed by name only") void testOverride3() { assertOptionalEquals("1", source.getString("fq_to_override")); } @Test @DisplayName("Name only in rhn_web.conf, overridden fully qualified in rhn.conf, accessed fully qualified") void testOverride4() { assertOptionalEquals("overridden", source.getString("web.to_override_without_prefix")); assertOptionalEquals("overridden", source.getString("to_override_without_prefix")); } @Test @DisplayName("Name only in rhn_web.conf, overridden name only in rhn.conf, accessed fully qualified") void testOverride5() { assertOptionalEquals("overridden", source.getString("to_override_without_prefix1")); assertOptionalEquals("overridden", source.getString("web.to_override_without_prefix1")); } } @Nested @DisplayName("Property collision behaviour") class CollisionTest { @Test @DisplayName("Multiple properties with the same name in different configuration file, accessed fully qualified") public void testCollision() { assertOptionalEquals("10", source.getString("web.collision")); assertOptionalEquals("12", source.getString("prefix.collision")); } @Test @DisplayName("Multiple properties with the same name in different configuration file, accessed without prefix") public void testFallbackNamespaceOrder() { assertOptionalEquals("10", source.getString("collision")); } } @Nested @DisplayName("Edge cases") class EdgeCasesTest { @Test @DisplayName("Trying to retrieve a null property") void testForNull() { assertOptionalEmpty(source.getString(null)); assertOptionalEmpty(source.getInteger(null)); assertOptionalEmpty(source.getBoolean(null)); assertOptionalEmpty(source.getList(null, String.class)); } @Test @DisplayName("A comment within property definition is considered part of the value") void testComment() { assertOptionalEquals( "#this will NOT be a comment!", source.getString("server.satellite.key_with_seeming_comment") ); } @Test @DisplayName("Parsing of backslash") void testBackSlashes() { assertOptionalEquals("we\\have\\backslashes", source.getString("server.satellite.key_with_backslash")); } } } 07070100000022000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003300000000uyuni-java-common/src/test/java/com/suse/common/io07070100000023000081A4000003E80000006400000001662798DF00001343000000000000000000000000000000000000004F00000000uyuni-java-common/src/test/java/com/suse/common/io/ByteSequenceFinderTest.java/* * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.suse.common.io; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.params.provider.Arguments.arguments; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.RepeatedTest; 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.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; class ByteSequenceFinderTest { private static final Random randomSource = new Random(); @ParameterizedTest(name = "Search sequence \"{1}\" within \"{1}\"") @DisplayName("Can find sequences of bytes within text") @MethodSource("textAndPatternProvider") void testSearch(String text, String pattern) throws IOException { byte[] data = text.getBytes(StandardCharsets.UTF_8); try (InputStream stream = new ByteArrayInputStream(data)) { ByteSequenceFinder finder = new ByteSequenceFinder(pattern.getBytes(StandardCharsets.UTF_8)); // Ensure both search methods gives the same result of index of int foundPosition = text.indexOf(pattern); assertEquals(foundPosition, finder.search(stream)); assertEquals(foundPosition, finder.search(data)); } } @RepeatedTest(50) @DisplayName("Does not fail on random byte sequences") void testRandomly() throws IOException { String dataString = randomAlphanumeric(1024); String sequenceString = randomAlphanumeric(64); byte[] data = dataString.getBytes(StandardCharsets.UTF_8); byte[] sequence = sequenceString.getBytes(StandardCharsets.UTF_8); try (InputStream stream = new ByteArrayInputStream(data)) { ByteSequenceFinder finder = new ByteSequenceFinder(); // Ensure it find itself stream.reset(); finder.setSequence(data); assertEquals(0, finder.search(stream)); assertEquals(0, finder.search(data)); // Ensure we get the same result of indexOf stream.reset(); finder.setSequence(sequence); assertEquals(dataString.indexOf(sequenceString), finder.search(stream)); assertEquals(dataString.indexOf(sequenceString), finder.search(data)); // Ensure we don't find something is not part of the data stream.reset(); finder.setSequence("@#$%^&&*".getBytes(StandardCharsets.UTF_8)); assertEquals(-1, finder.search(stream)); assertEquals(-1, finder.search(data)); } } @Test @DisplayName("Does not fail when the sequence contains -1") void testSequenceContainingMinusOne() throws IOException { byte[] sequence = {110, 29, -1, 107, 72}; byte[] data = {32, 26, -1, -20, 69, 110, 29, -1, 107, 72, 120, 14, -26, -1, -68}; try (InputStream stream = new ByteArrayInputStream(data)) { ByteSequenceFinder finder = new ByteSequenceFinder(sequence); assertEquals(5, finder.search(stream)); assertEquals(5, finder.search(data)); } } static Stream<Arguments> textAndPatternProvider() { return Stream.of( arguments("", ""), arguments("", "ab"), arguments("a", "a"), arguments("a", "b"), arguments("aaa", "aaaaa"), arguments("aaa", "abaaba"), arguments("abab", "abacababc"), arguments("abab", "babacaba"), arguments("aaacaaaaac", "aaacacaacaaacaaaacaaaaac"), arguments("ababcababdabababcababdaba", "ababcababdabababcababdaba") ); } public static String randomAlphanumeric(int length) { String allowedChars = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789"; return IntStream.range(0, length) .mapToObj(idx -> Character.toString(allowedChars.charAt(randomSource.nextInt(allowedChars.length())))) .collect(Collectors.joining()); } } 07070100000024000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002500000000uyuni-java-common/src/test/resources07070100000025000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002900000000uyuni-java-common/src/test/resources/com07070100000026000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000002E00000000uyuni-java-common/src/test/resources/com/suse07070100000027000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000003500000000uyuni-java-common/src/test/resources/com/suse/common07070100000028000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000004300000000uyuni-java-common/src/test/resources/com/suse/common/configuration07070100000029000041ED000003E80000006400000002662798DF00000000000000000000000000000000000000000000004B00000000uyuni-java-common/src/test/resources/com/suse/common/configuration/default0707010000002A000081A4000003E80000006400000001662798DF00000027000000000000000000000000000000000000006200000000uyuni-java-common/src/test/resources/com/suse/common/configuration/default/bug154517.conf.rpmsavebetternotfindme=Error if this is found.0707010000002B000081A4000003E80000006400000001662798DF00000026000000000000000000000000000000000000005700000000uyuni-java-common/src/test/resources/com/suse/common/configuration/default/random.fileproperty_definition=should be ignored 0707010000002C000081A4000003E80000006400000001662798DF000003D0000000000000000000000000000000000000005B00000000uyuni-java-common/src/test/resources/com/suse/common/configuration/default/rhn_prefix.confprefix.simple_value = value prefix.with_spaces = all trailing spaces should be trimmed prefix.empty = prefix.collision=12 prefix.comma_separated=every,good,boy,does,fine prefix.comma_no_trim=every, good , boy , does,fine prefix.array_one_element=some value prefix.foo = thirty-three # define a boolean value in rhn_prefix.conf, call getBoolean. # Test true, false, 1, 0, y, n, foo, 10 prefix.boolean_true = true prefix.boolean_false = false prefix.boolean_1 = 1 prefix.boolean_0 = 0 prefix.boolean_y = y prefix.boolean_Y = Y prefix.boolean_n = n prefix.boolean_yes = yes prefix.boolean_no = no prefix.boolean_on = on prefix.boolean_off = off prefix.boolean_foo = foo prefix.boolean_10 = 10 prefix.boolean_empty = prefix.boolean_on = on prefix.boolean_off = off # define an integer value in rhn_prefix.conf, call getInt. # Test -10, 0, 100, y prefix.int_minus10 = -10 prefix.int_zero = 0 prefix.int_100 = 100 prefix.int_y = y prefix.double = 10.0 prefix.float = 10.0 0707010000002D000081A4000003E80000006400000001662798DF00000145000000000000000000000000000000000000005800000000uyuni-java-common/src/test/resources/com/suse/common/configuration/default/rhn_web.confweb.property_with_prefix = this is a property with a prefix without_prefix = this is a property without a prefix web.to_override = 0 web.fq_to_override=0 to_override_without_prefix=override me to_override_without_prefix1=override me web.collision=10 web.product_name=Spacewalk java.taskomatic_cobbler_user = taskomatic_user 0707010000002E000081A4000003E80000006400000001662798DF000000F6000000000000000000000000000000000000004C00000000uyuni-java-common/src/test/resources/com/suse/common/configuration/rhn.confto_override=keep web.fq_to_override=1 web.to_override_without_prefix=overridden to_override_without_prefix1=overridden server.satellite.key_with_backslash=we\have\backslashes server.satellite.key_with_seeming_comment=#this will NOT be a comment! 0707010000002F000081A4000003E80000006400000001662798DF00000221000000000000000000000000000000000000003500000000uyuni-java-common/src/test/resources/log4j2-test.xml<?xml version="1.0" encoding="UTF-8"?> <!-- This file just provide a basic fallback configuration --> <!-- The actual configuration is performed at runtime programmatically in the Log4J class --> <Configuration name="Basic" status="warn"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%-15tn] %c{1} - %m%n"/> </Console> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> 07070100000030000081A4000003E80000006400000001662798DF00000205000000000000000000000000000000000000002C00000000uyuni-java-common/uyuni-java-common.changes------------------------------------------------------------------- Mon Apr 15 18:47:41 CEST 2024 - marina.latini@suse.com - version 5.0.3-0 * Fixed license to correctly use GPL-2.0-only ------------------------------------------------------------------- Fri Apr 05 15:27:13 CEST 2024 - marina.latini@suse.com - version 5.0.2-0 * Bump pom version ------------------------------------------------------------------- Thu Apr 04 23:43:12 CEST 2024 - marina.latini@suse.com - version 5.0.1-0 * Initial version 07070100000031000081A4000003E80000006400000001662798DF000006B8000000000000000000000000000000000000002900000000uyuni-java-common/uyuni-java-common.spec# # spec file for package uyuni-java-common # # Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: uyuni-java-common Version: 5.0.3 Release: 0 Summary: Common Java library for Uyuni Java components License: GPL-2.0-only Group: Development/Libraries/Java URL: https://www.uyuni-project.org Source0: %{name}-%{version}.tar.gz BuildRequires: fdupes BuildRequires: java-devel >= 11 BuildRequires: maven-local BuildRequires: mvn(org.uyuni-project:uyuni-java-parent:pom:) BuildRequires: mvn(org.apache.logging.log4j:log4j-api) BuildRequires: mvn(org.mybatis:mybatis) BuildRequires: mvn(com.mchange:c3p0) BuildArch: noarch %description A Java library containing basing utilities and functionalities shared among multiple Uyuni Java components. %package javadoc Summary: API documentation for %{name} %description javadoc %{summary}. %prep %setup -q %build %{mvn_build} -f %install %mvn_install %files -f .mfiles %defattr(-,root,root) %license LICENSE %files javadoc -f .mfiles-javadoc %license LICENSE %changelog 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor