Skip to content

ARTEMIS-1883 Improve FQQN validation#3365

Closed
rtista wants to merge 1 commit intoapache:mainfrom
rtista:artemis-1883
Closed

ARTEMIS-1883 Improve FQQN validation#3365
rtista wants to merge 1 commit intoapache:mainfrom
rtista:artemis-1883

Conversation

@rtista
Copy link

@rtista rtista commented Dec 1, 2020

This pull request improves the validation of Fully Qualified Queue Name (FQQN) strings as per issue ARTEMIS-1883 by validating the presence of content in both sides of the "::" separator.

@clebertsuconic
Copy link
Contributor

can you squash these commits and push -f?

@rtista
Copy link
Author

rtista commented Dec 1, 2020

can you squash these commits and push -f?

Yes of course! I am currently taking care of it ;)

@jbertram
Copy link
Contributor

jbertram commented Dec 2, 2020

@rtista, are you still working on this or should I updated it and send a PR of my own?

@rtista
Copy link
Author

rtista commented Dec 3, 2020

@rtista, are you still working on this or should I updated it and send a PR of my own?

Hey @jbertram , I've had a difficult day today but I'll make it up tomorrow! Sorry about the delay!

@jbertram
Copy link
Contributor

jbertram commented Dec 3, 2020

This looks good to me.

@rtista rtista closed this Dec 6, 2020
@rtista rtista reopened this Dec 6, 2020
@rtista
Copy link
Author

rtista commented Dec 6, 2020

Sorry, I inadvertently closed this :/

@rtista
Copy link
Author

rtista commented Dec 8, 2020

Ok guys, I just rebased against master and I think everything is ready! Whenever you're ready just accept it ;)

@clebertsuconic
Copy link
Contributor

@rtista I will run the whole test suite and if it's passing it's a good sign.. takes 2 hours to run it.

@clebertsuconic
Copy link
Contributor

@rtista / @jbertram this test fails with this PR:

org.apache.activemq.artemis.tests.integration.amqp.AmqpFullyQualifiedNameTest.testQueueSpecial

@clebertsuconic
Copy link
Contributor

clebertsuconic commented Dec 8, 2020

@rtista I actually had 3 failures, although I don't know if the BasicSecurityManagerFailoverTest is an intermittent / non related failure yet.

but the AmqpFullyQualifiedNameTest is definitely a real failure.

Test Name Duration Age
org.apache.activemq.artemis.tests.integration.amqp.AmqpFullyQualifiedNameTest.testQueueSpecial 79 ms 1
org.apache.activemq.artemis.tests.integration.security.BasicSecurityManagerFailoverTest.testFailover[replicated=true] 0.48 sec 1
org.apache.activemq.artemis.tests.integration.security.BasicSecurityManagerFailoverTest.testFailover[replicated=false] 0.27 sec 1

@rtista
Copy link
Author

rtista commented Dec 9, 2020

Thanks for the quick response @clebertsuconic, I was attempting to execute that same test in Intellij but I'm having what I believe is a different failure from yours:

[main] 00:04:44,964 ERROR [org.apache.activemq.artemis.core.client] AMQ214032: Unable to initialize VersionLoader : java.lang.NumberFormatException: For input string: "${activemq.version.majorVersion}"

I am probably missing some setup in order to run the test through Intellij.

I can see however that the test is attempting to create an invalid FQQN (since an empty address is being passed) and expecting it to fail as in the test doc says "Broker should return exception if no address is passed in FQQN".

@clebertsuconic
Copy link
Contributor

I see that happening in Intelij sometimes.

I don't know what magic I do. But I mix refreshing the workspace with the proper JDK. Pay attention to the profiles you have on. If you are on jdk8 only select jdk8 as the profile.

@rtista
Copy link
Author

rtista commented Dec 9, 2020

I just got it working by re-running install, maybe I missed something. Anyway, I already have that test failing with the expected exception not being thrown. I'll be chasing it tomorrow after work! Thanks for the help! ;)

@rtista
Copy link
Author

rtista commented Dec 13, 2020

Hey guys, I believe I've found out the reason to why the test is failing but I'm going to need some help on deciding how to proceed from here.

So, according to the Javadoc, the AmqpFullyQualifiedNameTest.testQueueSpecial test is expecting an exception to be raised when an "empty" address is passed in a FQQN, such as, "::q1". However, according to the implementation in this PR, "::q1" is no longer a valid FQQN since at least a single character needs to be present on each side of the separator.

I've tracked the variations in the data flow to two places in the activemq-artemis/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java class in the init() method.

  1. The first is an if statement checking a string for FQQN validation in the following lines:

https://github.com/apache/activemq-artemis/blob/87e507aecb1103fdce28d37bb340362e4e14de91/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java#L997-L1003

  • In the original version (before this PR modifications), the test would succeed as it would enter the first branch of the following if statement, assuming an empty string as the address and the queue name "q1":

  • With this PR modifications, the data flow enters the second branch (else) and populates the address variable with "::q1".

  1. The second data flow variation is further in the same method where an evaluation to null of the queueNameToUse variable is tested:

https://github.com/apache/activemq-artemis/blob/87e507aecb1103fdce28d37bb340362e4e14de91/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java#L1129-L1146

  • Once again, in the original version (before this PR modifications), the data flow follows through the first branch as queueNameToUse != null is true and the getMatchingQueue method throws the expected exception as the data flow follows into the second throws statement:

https://github.com/apache/activemq-artemis/blob/87e507aecb1103fdce28d37bb340362e4e14de91/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java#L1180-L1193

  • However, after this PR modifications, the data flow follows into the else branch as queueNameToUse != null is false which uses the sessionSPI.getMatchingQueue method and so the exception is no longer thrown as I believe a single "::q1" ANYCAST queue is created.

I am currently unsure as to how to proceed since I do not know if the behavior created by my modifications is expected in the AMQP protocol or not and would like to get some advice from you guys 😄

@clebertsuconic
Copy link
Contributor

The test is trying to open a queue with ::queue.. after your change this is being considered a regular queue, which is not what it should be doing.

it seems the opposite of what you're changing.

@clebertsuconic
Copy link
Contributor

To do what you're proposing, you would need some pedantic mode where you would throw an exception with something invalidException. however this type of semantic change may break other things..

Do you really want this PR? I think we should consider leaving it as is.

@rtista
Copy link
Author

rtista commented Dec 14, 2020

@clebertsuconic I fully understand your concerns, I could also just check for presence of characters on the right side of the separator. This would strengthen the validation by always checking for the queue part at least but ignoring the address which would still allow that test to succesfuly pass.

I guess I'd like to hear more opinions though, such as @jbertram's and @michaelandrepearce's, before closing the PR as something that would cause more harm than good 😜

Regarding the PR, I do not "want" the PR, I was just looking to contribute. I picked up this Jira issue as it seemed like a good first issue in a large project such as this one. If you can direct me to other good Jira's for starting up artemis contributions I'd be delighted x)

@clebertsuconic
Copy link
Contributor

@rtista I see.. I thought you were having an issue you were facing and wanted this.

I will wait on others opinion on this.

@jbertram
Copy link
Contributor

In principal, I liked the idea of tightening the rules for FQQN validation, but it's obviously causing other issues. Perhaps the method should throw an exception if the input is not a valid FQQN but it still contains the separator (i.e. ::). That may cover all the necessary cases, but it could cause more problems as well. I'm not sure at this point. In any event, I'm happy to merge the PR if there are no test failures, but as it stands now it can't be merged.

@rtista
Copy link
Author

rtista commented Dec 20, 2020

Hey @jbertram and @clebertsuconic! I partially agree with the desired behavior you guys described and I don't mind implementing it and dealing with the errors that may arise from it. However, most usages of the isfullyQualified method are in if statements and it seems to me that adding the exception throwing behavior will render this code (which calls isfullyQualified) confusing.

I believe it would make more sense to throw an exception in methods such as toFullyQualified, extractQueueName and extractAddressName than in isFullyQualified since the latter is used by its callers to create logic variations when a provided string is not in FQQN format. While some clients may wish to throw an exception because they only support FQQN syntax, others may wish to fallback to another behavior such as creating an ANYCAST queue with the string provided.

I have tracked usages of CompositeAddress.isfullyQualified to the following files:

[artista@astartes activemq-artemis]$ find . -type f -name "*.java" -exec grep -l "CompositeAddress.isFullyQualified(" {} \;
./artemis-cli/src/test/java/org/apache/activemq/cli/test/CliProducerTest.java
./artemis-cli/src/test/java/org/apache/activemq/cli/test/MessageSerializerTest.java
./artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueConfiguration.java
./artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
./artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java
./artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQConsumer.java
./artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQSession.java
./artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java
./artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompSession.java
./artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/BindingsImpl.java
./artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
./artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
./artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java

The usages themselves are as follow where it is possible to see the high amount of if statements:

[artista@astartes activemq-artemis]$ grep isFullyQualified -r | grep ".java:"
artemis-cli/src/test/java/org/apache/activemq/cli/test/CliProducerTest.java:      List<Message> received = consumeMessages(session, address, TEST_MESSAGE_COUNT, CompositeAddress.isFullyQualified(address));
artemis-cli/src/test/java/org/apache/activemq/cli/test/MessageSerializerTest.java:      List<Message> received = consumeMessages(session, address, TEST_MESSAGE_COUNT, CompositeAddress.isFullyQualified(address));
artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueConfiguration.java:      if (CompositeAddress.isFullyQualified(address)) {
artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueConfiguration.java:      if (CompositeAddress.isFullyQualified(name)) {
artemis-commons/src/main/java/org/apache/activemq/artemis/utils/CompositeAddress.java:   public static boolean isFullyQualified(String address) throws ActiveMQInvalidQueueConfiguration {
artemis-commons/src/main/java/org/apache/activemq/artemis/utils/CompositeAddress.java:   public static boolean isFullyQualified(SimpleString address) throws ActiveMQInvalidQueueConfiguration {
artemis-commons/src/main/java/org/apache/activemq/artemis/utils/CompositeAddress.java:      return address != null && isFullyQualified(address.toString());
artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java:            } else if (CompositeAddress.isFullyQualified(address)) { // it could be a topic using FQQN
artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java:               if (!CompositeAddress.isFullyQualified(dest.getAddress())) {
artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java:            if (CompositeAddress.isFullyQualified(source.getAddress())) {
artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQConsumer.java:         if (CompositeAddress.isFullyQualified(physicalName)) {
artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQSession.java:                  if (CompositeAddress.isFullyQualified(queueName.toString())) {
artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java:         if ((CompositeAddress.isFullyQualified(destination) || effectiveAddressRoutingType == RoutingType.ANYCAST) && addressSettings.isAutoCreateQueues() && manager.getServer().locateQueue(simpleDestination) == null) {
artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompSession.java:      if (multicast && !CompositeAddress.isFullyQualified(destination)) {
artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/BindingsImpl.java:         } else if (CompositeAddress.isFullyQualified(message.getAddress())) {
artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java:            if (!newFQQN && CompositeAddress.isFullyQualified(address.toString())) {
artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java:         securityCheck(CompositeAddress.extractAddressName(art.getName()), CompositeAddress.isFullyQualified(art.getName()) ? CompositeAddress.extractQueueName(art.getName()) : null, CheckType.SEND, this);
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:   public void testIsFullyQualifiedInvalidFQQN() throws ActiveMQInvalidQueueConfiguration {
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:      CompositeAddress.isFullyQualified(failureScenario);
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:   public void testIsFullyQualifiedNullQueue() throws ActiveMQInvalidQueueConfiguration {
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:      CompositeAddress.isFullyQualified(nullableQueueScenario);
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:   public void testIsFullyQualifiedNullAddress() throws ActiveMQInvalidQueueConfiguration {
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:      CompositeAddress.isFullyQualified(nullableAddressScenario);
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:   public void testIsFullyQualifiedSuccess() throws ActiveMQInvalidQueueConfiguration {
artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/CompositeAddressTest.java:      assertTrue("Valid FQQN was not validated.", CompositeAddress.isFullyQualified(successScenario));

Let me know what you think about this.

@michaelandrepearce
Copy link
Contributor

michaelandrepearce commented Dec 20, 2020

-1 to throwing exceptions and changing behaviour. It will cause the jvm to capture stack traces unneeded. Remember this is hot path code that affects end2end message latency/perf

Id like to see some end2end perf stats on changes here too before it can be merged. Not just for fqqn but non fqqn as well.

@rtista
Copy link
Author

rtista commented Dec 21, 2020

Hey @michaelandrepearce, after I developed the code I ran some arguably worthy performance tests to the function. They are not e2e however. I simply recorded the execution time of the function for one hundred million executions and calculated the mean. Here's the code I used:

int sum = 0;
final int TEST_TIMES = 100000000;
final String TEST_STRING = "address::queue";
long startTime;
long stopTime;

for (int i = 0 ; i < TEST_TIMES ; i++) {
   startTime = System.nanoTime();
   CompositeAddress.isFullyQualifiedOld(TEST_STRING);
   stopTime = System.nanoTime();
   sum += (stopTime - startTime);
}

System.out.println("Before FQQN Performance: " + (sum / TEST_TIMES));

sum = 0;

for (int i = 0 ; i < TEST_TIMES ; i++) {
   startTime = System.nanoTime();
   CompositeAddress.isFullyQualified(TEST_STRING);
   stopTime = System.nanoTime();
   sum += (stopTime - startTime);
}

System.out.println("After FQQN Performance: " + (sum / TEST_TIMES));

I executed this code for "address::queue", "::queue", "address::" and null and here are the results:

Test String Before (ns) After (ns)
"address::queue" 20 ns 20 ns
"::queue" 19 ns 19 ns
"address::" 20 ns 20 ns
null 16 ns 16 ns

I understand however that these tests might not carry any real meaning to you, but if you're able to direct me to an example of what you need I can surely try to provide those results to you ;)

@franz1981
Copy link
Contributor

franz1981 commented Dec 21, 2020

Hi @rtista please use JMH to produce a valid benchmark: see
https://github.com/apache/activemq-artemis/blob/68ffe0780e6b1709c92f3d9f81d7145d1022e9a9/tests/performance-jmh/src/main/java/org/apache/activemq/artemis/tests/performance/jmh/ByteArrayHashCodeBenchamark.java
Using the same test string won't work, considering what the JVM can do: I can help to get a valid benchmark done

@michaelandrepearce
Copy link
Contributor

michaelandrepearce commented Dec 21, 2020

@franz1981 Can we have some e2e ones. These microbenchmarks dont cater for the system as a whole. Of recent weve dropped about 12k in throughput in the last yrs (see the public softwaremill perf report this yr (52k) vs 2 yrs back (64k) ) so we gotta get better at ensuring we dont regress or slowley erode e2e perf.

See here

https://softwaremill.com/mqperf/

vs

https://softwaremill.com/mqperf-2017

@franz1981
Copy link
Contributor

franz1981 commented Dec 21, 2020

@michaelandrepearce i have had some personal issue this year so haven't yet fixed that drop, will look at it with the new year and I am trusty can be fixed. At least we don't exhibit the perf scalability issue shown on https://issues.apache.org/jira/browse/ARTEMIS-2852.
I am sure that the perf drop mostly depends by the GC used: we were using parallel new before while g1gc (that we use now) has a slower peak throughput...
I would like to suggest some apple 2 apple GC and heap configuration to verify if we had a real perf drop.
Agree on e2e :)

@franz1981
Copy link
Contributor

@michaelandrepearce And I was wrong: I see that Artemis 2.2.0 is using G1GC:

JAVA_ARGS=" -XX:+PrintClassHistogram -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx2G"

The only relevant difference is the string deduplication (that can add some latency spike) and the heap size, global max size.
I'm going to create a separate JIRA to handle this perf regression: probably worth to spent some time to dig what's going on here

@rtista
Copy link
Author

rtista commented Dec 26, 2020

Hey guys, hope you all had a Merry Christmas! ;)

@franz1981 I think I was able to implement the JMH tests you were looking for, here's the JMH benchmark class I created:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.activemq.artemis.tests.performance.jmh;

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

public class CompositeAddressBenchmark {

    /* The FQQN separator */
    public static final String SEPARATOR = "::";

    /* The FQQN separator length */
    public static final int SEPARATOR_LENGTH = SEPARATOR.length();

    @State(Scope.Benchmark)
    public static class BenchmarkState {

        @Param({"address::queue", "address::", "::queue", "::"})
        public String queue;
    }

    /**
     * Code for isFullyQualified before Artemis-1883 changes.
     * @return boolean
     */
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Fork(value = 1, warmups = 1)
    @Warmup(iterations = 1)
    public static boolean isFullyQualifiedBefore(BenchmarkState state) {
        return state.queue != null && state.queue.contains(SEPARATOR);
    }

    /**
     * Code for isFullyQualified after Artemis-1883 changes.
     * @return boolean
     */
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Fork(value = 1, warmups = 1)
    @Warmup(iterations = 1)
    public static boolean isFullyQualifiedAfter(BenchmarkState state) {

        if (state.queue == null) {
            return false;
        }

        // If address length is incapable of holding the separator and two more characters
        if (state.queue.length() < SEPARATOR_LENGTH + 2) {
            return false;
        }

        // If separator is not found or is at the start or end of string then this is not a FQQN
        int index = state.queue.indexOf(SEPARATOR, 1);
        return index != -1 && index != state.queue.length() - SEPARATOR_LENGTH;
    }
}

And here are the results:

# Run complete. Total time: 00:16:03

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark                                                (queue)  Mode  Cnt  Score   Error  Units
CompositeAddressBenchmark.isFullyQualifiedAfter   address::queue  avgt    5  7.410 ± 1.155  ns/op
CompositeAddressBenchmark.isFullyQualifiedAfter        address::  avgt    5  7.954 ± 0.076  ns/op
CompositeAddressBenchmark.isFullyQualifiedAfter          ::queue  avgt    5  7.408 ± 0.086  ns/op
CompositeAddressBenchmark.isFullyQualifiedAfter               ::  avgt    5  3.026 ± 1.172  ns/op
CompositeAddressBenchmark.isFullyQualifiedBefore  address::queue  avgt    5  6.507 ± 0.106  ns/op
CompositeAddressBenchmark.isFullyQualifiedBefore       address::  avgt    5  6.407 ± 0.461  ns/op
CompositeAddressBenchmark.isFullyQualifiedBefore         ::queue  avgt    5  6.667 ± 1.218  ns/op
CompositeAddressBenchmark.isFullyQualifiedBefore              ::  avgt    5  6.378 ± 0.521  ns/op

I haven't pushed the class code as I thought you'd probably want to mess with the warmup, fork and iterations parameters I guess in order to improve the results.

Also, @franz1981 is there any way you can direct me to a framework for the E2E tests @michaelandrepearce is looking for?

@jbertram
Copy link
Contributor

jbertram commented Jun 7, 2021

You've done some good work on this PR, @rtista. However, I think that this is ultimately a solution looking for a problem that doesn't actually exist.

As currently written and used throughout the code-base, the isFullyQualified method is meant to denote whether or not any attempt to use FQQN was made, not necessarily whether or not it is semantically valid. Therefore, input like ::foo and foo:: will result in true because they contain ::. However, they may result in exceptions later since they are not semantically valid.

Given this I'm closing this PR.

@jbertram jbertram closed this Jun 7, 2021
@jbertram
Copy link
Contributor

jbertram commented Jun 7, 2021

To be clear, I committed a38f009 to clarify the docs.

@rtista
Copy link
Author

rtista commented Jun 7, 2021

You've done some good work on this PR, @rtista. However, I think that this is ultimately a solution looking for a problem that doesn't actually exist.

As currently written and used throughout the code-base, the isFullyQualified method is meant to denote whether or not any attempt to use FQQN was made, not necessarily whether or not it is semantically valid. Therefore, input like ::foo and foo:: will result in true because they contain ::. However, they may result in exceptions later since they are not semantically valid.

Given this I'm closing this PR.

@jbertram Not a problem! Glad of what I've already learned from you guys so far! I'll be picking other Jira Issues for fun 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants