From users-return-51273-archive-asf-public=cust-asf.ponee.io@activemq.apache.org Mon Apr 8 18:26:20 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 594C6180627 for ; Mon, 8 Apr 2019 20:26:20 +0200 (CEST) Received: (qmail 67678 invoked by uid 500); 8 Apr 2019 18:06:42 -0000 Mailing-List: contact users-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@activemq.apache.org Delivered-To: mailing list users@activemq.apache.org Delivered-To: moderator for users@activemq.apache.org Received: (qmail 30667 invoked by uid 99); 8 Apr 2019 17:56:21 -0000 X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 2.621 X-Spam-Level: ** X-Spam-Status: No, score=2.621 tagged_above=-999 required=6.31 tests=[RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_PASS=-0.001, SPF_SOFTFAIL=0.972, URIBL_BLOCKED=0.001, URI_HEX=1.313, URI_TRY_3LD=0.336] autolearn=disabled Date: Mon, 8 Apr 2019 13:15:54 -0500 (CDT) From: "juan.buireo" To: users@activemq.apache.org Message-ID: <1554747354456-0.post@n4.nabble.com> Subject: Comparator implementation of HierarchicalObjectRepository issue MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I am having an issue with the MatchComparator implemented in the HierarchicalObjectRepository class. Let me put an example on what's going on right now: I have created a class called DynamicRolesSecuritySettingPlugin implementing the interface SecuritySettingPlugin so that I can implement the setSecurityRepository method. There, I am adding some roles to the HierarchicalRepository based on a certificate. The HierarchicalRepository type T is Set. To summarize, the HierarchicalObjectRepository ends up having two different strings as key to the internal map (they are added with the addMatch method): - *.Provider.*.Agent.*.State - uswest.Provider.RR.Agent.*.State For the string "*.Provider.*.Agent.*.State", i end up setting a Role with permissions to publish but not to consume. For the string "uswest.Provider.RR.Agent.*.State", i end up setting a Role with permissions to consume. Now, when I create a consumer for a queue named uswest.Provider.RR.Agent.1.State (there is already a queue created with that name and with messages on it), I get an error on the consumer saying that I don't have the permission 'CONSUME' for queue uswest.Provider.RR.Agent.1.State. So I went ahead and debugged the code. I ended up in the class HierarchicalObjectRepository reading the getMatch method: @Override public T getMatch(final String match) { String modifiedMatch = matchModifier.modify(match); T cacheResult = cache.get(modifiedMatch); if (cacheResult != null) { return cacheResult; } lock.readLock().lock(); try { T actualMatch; Map> possibleMatches = getPossibleMatches(modifiedMatch); Collection> orderedMatches = sort(possibleMatches); actualMatch = merge(orderedMatches); T value = actualMatch != null ? actualMatch : defaultmatch; if (value != null) { cache.put(modifiedMatch, value); } return value; } finally { lock.readLock().unlock(); } } When I set a breakpoint in the getPossibleMatches I get the two entries correctly (both "*.Provider.*.Agent.*.State" and "uswest.Provider.RR.Agent.*.State"). Then when i see the sort method, i see that I do get first the "*.Provider.*.Agent.*.State" instead of the "uswest.Provider.RR.Agent.*State". As I said before, the role attached to "*.Provider.*.Agent.*.State" does not have permission to consume on the queue "uswest.Provider.RR.Agent.1.State" and that is the reason why I can't consume. When I looked at the comparator (MatchComparator) that decides which one should be first in the list, I see the following code: if (o1.contains(anyWords) && !o2.contains(anyWords)) { return +1; } else if (!o1.contains(anyWords) && o2.contains(anyWords)) { return -1; } else if (o1.contains(anyWords) && o2.contains(anyWords)) { return o2.length() - o1.length(); } else if (o1.contains(singleWord) && !o2.contains(singleWord)) { return +1; } else if (!o1.contains(singleWord) && o2.contains(singleWord)) { return -1; } else if (o1.contains(singleWord) && o2.contains(singleWord)) { String[] leftSplits = o1.split(quotedDelimiter); String[] rightSplits = o2.split(quotedDelimiter); for (int i = 0; i < leftSplits.length; i++) { String left = leftSplits[i]; if (left.equals(singleWord)) { if (rightSplits.length < i || !rightSplits[i].equals(singleWord)) { return -1; } else { return +1; } } } } return o1.length() - o2.length(); Since in this case both strings contains the "*" it goes through the last else if and this is what ends up doing the comparation: String[] leftSplits = o1.split(quotedDelimiter); String[] rightSplits = o2.split(quotedDelimiter); for (int i = 0; i < leftSplits.length; i++) { String left = leftSplits[i]; if (left.equals(singleWord)) { if (rightSplits.length < i || !rightSplits[i].equals(singleWord)) { return -1; } else { return +1; } } } This ends up returning the "*.Provider.*.Agent.*.State" when it shouldn't. There is a more specific string for the queue "uswest.Provider.RR.Agent.1.State". It's not taking into account the amount of "*" present in the string. -- Sent from: http://activemq.2283324.n4.nabble.com/ActiveMQ-User-f2341805.html