private static void checkRequiredParameter(String url, String val) { if (!url.contains(val)) { throw new MessageException(format("JDBC URL must have the property '%s'", val)); } }
@Test public void addFromMandatoryProperty_throws_IAE_if_option_starts_with_prefix_of_mandatory_option_but_has_different_value() { String[] optionOverrides = { randomPrefix, randomPrefix + randomValue.substring(1), randomPrefix + randomValue.substring(1), randomPrefix + randomValue.substring(2), randomPrefix + randomValue.substring(3), randomPrefix + randomValue.substring(3) + randomAlphanumeric(1), randomPrefix + randomValue.substring(3) + randomAlphanumeric(2), randomPrefix + randomValue.substring(3) + randomAlphanumeric(3), randomPrefix + randomValue + randomAlphanumeric(1) }; JvmOptions underTest = new JvmOptions(ImmutableMap.of(randomPrefix, randomValue)); for (String optionOverride : optionOverrides) { try { properties.put(randomPropertyName, optionOverride); underTest.addFromMandatoryProperty(new Props(properties), randomPropertyName); fail("an MessageException should have been thrown"); } catch (MessageException e) { assertThat(e.getMessage()) .isEqualTo("a JVM option can't overwrite mandatory JVM options. " + "The following JVM options defined by property '" + randomPropertyName + "' are invalid: " + optionOverride + " overwrites " + randomPrefix + randomValue); } } }
@Test public void add_throws_MessageException_if_option_starts_with_prefix_of_mandatory_option_but_has_different_value() { String[] optionOverrides = { randomPrefix, randomPrefix + randomAlphanumeric(1), randomPrefix + randomAlphanumeric(2), randomPrefix + randomAlphanumeric(3), randomPrefix + randomAlphanumeric(4), randomPrefix + randomValue.substring(1), randomPrefix + randomValue.substring(2), randomPrefix + randomValue.substring(3) }; JvmOptions underTest = new JvmOptions(ImmutableMap.of(randomPrefix, randomValue)); for (String optionOverride : optionOverrides) { try { underTest.add(optionOverride); fail("an MessageException should have been thrown"); } catch (MessageException e) { assertThat(e.getMessage()).isEqualTo("a JVM option can't overwrite mandatory JVM options. " + optionOverride + " overwrites " + randomPrefix + randomValue); } } }
public MinimumViableSystem checkRequiredJavaOptions(Map<String, String> requiredJavaOptions) { for (Map.Entry<String, String> entry : requiredJavaOptions.entrySet()) { String value = System.getProperty(entry.getKey()); if (!StringUtils.equals(value, entry.getValue())) { throw new MessageException(format( "JVM option '%s' must be set to '%s'. Got '%s'", entry.getKey(), entry.getValue(), StringUtils.defaultString(value))); } } return this; } }
String driverPath(File homeDir, Provider provider) { String dirPath = provider.path; File dir = new File(homeDir, dirPath); if (!dir.exists()) { throw new MessageException("Directory does not exist: " + dirPath); } List<File> files = new ArrayList<>(FileUtils.listFiles(dir, new String[] {"jar"}, false)); if (files.isEmpty()) { throw new MessageException("Directory does not contain JDBC driver: " + dirPath); } if (files.size() > 1) { throw new MessageException("Directory must contain only one JAR file: " + dirPath); } return files.get(0).getAbsolutePath(); }
private static void checkOptionFormat(String propertyName, List<String> jvmOptionsFromProperty) { List<String> invalidOptions = jvmOptionsFromProperty.stream() .filter(JvmOptions::isInvalidOption) .collect(Collectors.toList()); if (!invalidOptions.isEmpty()) { throw new MessageException(format( "a JVM option can't be empty and must start with '-'. The following JVM options defined by property '%s' are invalid: %s", propertyName, invalidOptions.stream() .collect(joining(", ")))); } }
private static String requireValue(Props props, String key) { String value = props.value(key); if (isBlank(value)) { throw new MessageException(format("Property %s is mandatory", key)); } return value; }
private void checkMandatoryOptionOverwrite(String value) { Map.Entry<String, String> overriddenMandatoryOption = mandatoryOptionFor(value); if (overriddenMandatoryOption != null) { throw new MessageException(String.format( "a JVM option can't overwrite mandatory JVM options. %s overwrites %s", value, overriddenMandatoryOption.getKey() + overriddenMandatoryOption.getValue())); } }
private void ensureNotLoopbackAddresses(Props props, String propertyKey) { stream(requireValue(props, propertyKey).split(",")) .filter(StringUtils::isNotBlank) .map(StringUtils::trim) .map(s -> StringUtils.substringBefore(s, ":")) .forEach(ip -> { try { if (network.isLoopbackInetAddress(network.toInetAddress(ip))) { throw new MessageException(format("Property %s must not be a loopback address: %s", propertyKey, ip)); } } catch (UnknownHostException e) { throw new MessageException(format("Property %s must not a valid address: %s [%s]", propertyKey, ip, e.getMessage())); } }); }
private void ensureLocalButNotLoopbackAddress(Props props, String propertyKey) { String propertyValue = props.nonNullValue(propertyKey).trim(); try { InetAddress address = network.toInetAddress(propertyValue); if (!network.isLocalInetAddress(address) || network.isLoopbackInetAddress(address)) { throw new MessageException(format("Property %s must be a local non-loopback address: %s", propertyKey, propertyValue)); } } catch (UnknownHostException | SocketException e) { throw new MessageException(format("Property %s must be a local non-loopback address: %s [%s]", propertyKey, propertyValue, e.getMessage())); } }
private static void ensureNotH2(Props props) { String jdbcUrl = props.value(JDBC_URL.getKey()); if (isBlank(jdbcUrl) || jdbcUrl.startsWith("jdbc:h2:")) { throw new MessageException("Embedded database is not supported in cluster mode"); } }
private static void verifyUnchanged(Props initialProps, Props newProps, String propKey) { String initialValue = initialProps.nonNullValue(propKey); String newValue = newProps.nonNullValue(propKey); if (!Objects.equals(initialValue, newValue)) { throw new MessageException(format("Property [%s] cannot be changed on restart: [%s] => [%s]", propKey, initialValue, newValue)); } }
private void checkMandatoryOptionOverwrite(String propertyName, List<String> jvmOptionsFromProperty) { List<Match> matches = jvmOptionsFromProperty.stream() .map(jvmOption -> new Match(jvmOption, mandatoryOptionFor(jvmOption))) .filter(match -> match.getMandatoryOption() != null) .collect(Collectors.toList()); if (!matches.isEmpty()) { throw new MessageException(format( "a JVM option can't overwrite mandatory JVM options. The following JVM options defined by property '%s' are invalid: %s", propertyName, matches.stream() .map(m -> m.getOption() + " overwrites " + m.mandatoryOption.getKey() + m.mandatoryOption.getValue()) .collect(joining(", ")))); } }
private static NodeType toNodeType(Props props) { String nodeTypeValue = requireValue(props, CLUSTER_NODE_TYPE.getKey()); if (!NodeType.isValid(nodeTypeValue)) { throw new MessageException(format("Invalid value for property %s: [%s], only [%s] are allowed", CLUSTER_NODE_TYPE.getKey(), nodeTypeValue, Arrays.stream(NodeType.values()).map(NodeType::getValue).collect(joining(", ")))); } return NodeType.parse(nodeTypeValue); }
private RollingPolicy createRollingPolicy(File logDir, String filenamePrefix) { String rollingPolicy = props.value(ROLLING_POLICY_PROPERTY, "time:yyyy-MM-dd"); int maxFiles = props.valueAsInt(MAX_FILES_PROPERTY, 7); if (maxFiles <= 0) { maxFiles = UNLIMITED_MAX_FILES; } if (rollingPolicy.startsWith("time:")) { return new TimeRollingPolicy(filenamePrefix, logDir, maxFiles, StringUtils.substringAfter(rollingPolicy, "time:")); } else if (rollingPolicy.startsWith("size:")) { return new SizeRollingPolicy(filenamePrefix, logDir, maxFiles, StringUtils.substringAfter(rollingPolicy, "size:")); } else if ("none".equals(rollingPolicy)) { return new NoRollingPolicy(filenamePrefix, logDir); } else { throw new MessageException(format("Unsupported value for property %s: %s", ROLLING_POLICY_PROPERTY, rollingPolicy)); } }
public RollingPolicy createRollingPolicy(Context ctx, Props props, String filenamePrefix) { String rollingPolicy = props.value(ROLLING_POLICY_PROPERTY, "time:yyyy-MM-dd"); int maxFiles = props.valueAsInt(MAX_FILES_PROPERTY, 7); File logsDir = props.nonNullValueAsFile(PATH_LOGS.getKey()); if (rollingPolicy.startsWith("time:")) { return new TimeRollingPolicy(ctx, filenamePrefix, logsDir, maxFiles, StringUtils.substringAfter(rollingPolicy, "time:")); } else if (rollingPolicy.startsWith("size:")) { return new SizeRollingPolicy(ctx, filenamePrefix, logsDir, maxFiles, StringUtils.substringAfter(rollingPolicy, "size:")); } else if ("none".equals(rollingPolicy)) { return new NoRollingPolicy(ctx, filenamePrefix, logsDir, maxFiles); } else { throw new MessageException(format("Unsupported value for property %s: %s", ROLLING_POLICY_PROPERTY, rollingPolicy)); } }
@Override public void registerClusterName(String clusterName) { IAtomicReference<String> property = hzMember.getAtomicReference(CLUSTER_NAME); if (property.get() == null) { Lock lock = hzMember.getLock(CLUSTER_NAME); lock.lock(); try { if (property.get() == null) { property.set(clusterName); } } finally { lock.unlock(); } } String clusterValue = property.get(); if (!property.get().equals(clusterName)) { throw new MessageException( format("This node has a cluster name [%s], which does not match [%s] from the cluster", clusterName, clusterValue)); } }
Provider resolveProviderAndEnforceNonnullJdbcUrl(Props props) { String url = props.value(JDBC_URL.getKey()); Integer embeddedDatabasePort = props.valueAsInt(JDBC_EMBEDDED_PORT.getKey()); if (embeddedDatabasePort != null) { String correctUrl = buildH2JdbcUrl(embeddedDatabasePort); warnIfUrlIsSet(embeddedDatabasePort, url, correctUrl); props.set(JDBC_URL.getKey(), correctUrl); return Provider.H2; } if (isEmpty(url)) { props.set(JDBC_URL.getKey(), buildH2JdbcUrl(JDBC_EMBEDDED_PORT_DEFAULT_VALUE)); props.set(JDBC_EMBEDDED_PORT.getKey(), String.valueOf(JDBC_EMBEDDED_PORT_DEFAULT_VALUE)); return Provider.H2; } Pattern pattern = Pattern.compile("jdbc:(\\w+):.+"); Matcher matcher = pattern.matcher(url); if (!matcher.find()) { throw new MessageException(format("Bad format of JDBC URL: %s", url)); } String key = matcher.group(1); try { return Provider.valueOf(StringUtils.upperCase(key)); } catch (IllegalArgumentException e) { throw new MessageException(format("Unsupported JDBC driver provider: %s", key)); } }
private void checkClusterProperties(Props props) { // for internal use if (props.value(CLUSTER_WEB_STARTUP_LEADER.getKey()) != null) { throw new MessageException(format("Property [%s] is forbidden", CLUSTER_WEB_STARTUP_LEADER.getKey())); } NodeType nodeType = toNodeType(props); switch (nodeType) { case APPLICATION: ensureNotH2(props); requireValue(props, AUTH_JWT_SECRET.getKey()); ensureNotLoopbackAddresses(props, CLUSTER_HZ_HOSTS.getKey()); break; case SEARCH: requireValue(props, SEARCH_HOST.getKey()); ensureLocalButNotLoopbackAddress(props, SEARCH_HOST.getKey()); if (props.contains(CLUSTER_NODE_HZ_PORT.getKey())) { LoggerFactory.getLogger(getClass()).warn("Property {} is ignored on search nodes since 7.2", CLUSTER_NODE_HZ_PORT.getKey()); } break; default: throw new UnsupportedOperationException("Unknown value: " + nodeType); } requireValue(props, CLUSTER_NODE_HOST.getKey()); ensureLocalButNotLoopbackAddress(props, CLUSTER_NODE_HOST.getKey()); ensureNotLoopbackAddresses(props, CLUSTER_SEARCH_HOSTS.getKey()); }
private static void checkRequiredParameter(String url, String val) { if (!url.contains(val)) { throw new MessageException(format("JDBC URL must have the property '%s'", val)); } }