Author: orudyy Date: Tue Jun 9 11:14:07 2015 New Revision: 1684380 URL: http://svn.apache.org/r1684380 Log: QPID-6578: [Java Broker] Add the ability for logging filters to be added/removed/changed dynamically
Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/AbstractBrokerLogger.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/CompositeFilter.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerLoggerTest.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterTest.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/CompositeFilterTest.java Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerConsoleLoggerImpl.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerMemoryLoggerImpl.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilter.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterImpl.java qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/AbstractBrokerLogger.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/AbstractBrokerLogger.java?rev=1684380&view=auto ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/AbstractBrokerLogger.java (added) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/AbstractBrokerLogger.java Tue Jun 9 11:14:07 2015 @@ -0,0 +1,126 @@ +/* + * + * 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.i + * + */ +package org.apache.qpid.server.logging; + +import java.util.Map; + + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerLogger; +import org.apache.qpid.server.model.BrokerLoggerFilter; +import org.apache.qpid.server.model.ConfigurationChangeListener; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractBrokerLogger<X extends AbstractBrokerLogger<X>> extends AbstractConfiguredObject<X> implements BrokerLogger<X>, ConfigurationChangeListener +{ + protected CompositeFilter _compositeFilter = new CompositeFilter(); + + protected AbstractBrokerLogger(Map<String, Object> attributes, Broker<?> broker) + { + super(parentsMap(broker), attributes); + } + + protected CompositeFilter getCompositeFilter() + { + return _compositeFilter; + } + + @Override + protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + final ListenableFuture<C> filterFuture = getObjectFactory().createAsync(childClass, attributes, this); + doAfter(filterFuture, new CallableWithArgument<ListenableFuture<C>, C>() + { + @Override + public ListenableFuture<C> call(final C child) throws Exception + { + BrokerLoggerFilter<?> filter = (BrokerLoggerFilter) child; + filter.addChangeListener(AbstractBrokerLogger.this); + getCompositeFilter().addFilter(filter); + return Futures.immediateFuture(child); + } + }); + return filterFuture; + } + + @Override + public void stateChanged(ConfiguredObject<?> object, State oldState, State newState) + { + if (newState == State.DELETED && object instanceof BrokerLoggerFilter) + { + getCompositeFilter().removeFilter((BrokerLoggerFilter)object); + object.removeChangeListener(this); + } + } + + @Override + public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child) + { + // no-op + } + + @Override + public void childRemoved(ConfiguredObject<?> object, ConfiguredObject<?> child) + { + // no-op + } + + @Override + public void attributeSet(ConfiguredObject<?> object, String attributeName, Object oldAttributeValue, Object newAttributeValue) + { + // no-op + } + + @Override + public void bulkChangeStart(ConfiguredObject<?> object) + { + // no-op + } + + @Override + public void bulkChangeEnd(ConfiguredObject<?> object) + { + // no-op + } + + protected void initializeAppender(Appender<ILoggingEvent> appender) + { + ch.qos.logback.classic.Logger rootLogger = + (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + LoggerContext loggerContext = rootLogger.getLoggerContext(); + + appender.setContext(loggerContext); + + CompositeFilter compositeFilter = getCompositeFilter(); + compositeFilter.addFilters(getChildren(BrokerLoggerFilter.class)); + appender.addFilter(compositeFilter); + appender.setName(getName()); + } +} Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerConsoleLoggerImpl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerConsoleLoggerImpl.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerConsoleLoggerImpl.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerConsoleLoggerImpl.java Tue Jun 9 11:14:07 2015 @@ -29,13 +29,11 @@ import ch.qos.logback.core.ConsoleAppend import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.BrokerLoggerFilter; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; -public class BrokerConsoleLoggerImpl extends AbstractConfiguredObject<BrokerConsoleLoggerImpl> implements BrokerConsoleLogger<BrokerConsoleLoggerImpl> +public class BrokerConsoleLoggerImpl extends AbstractBrokerLogger<BrokerConsoleLoggerImpl> implements BrokerConsoleLogger<BrokerConsoleLoggerImpl> { @ManagedAttributeField private String _layout; @@ -43,7 +41,7 @@ public class BrokerConsoleLoggerImpl ext @ManagedObjectFactoryConstructor protected BrokerConsoleLoggerImpl(final Map<String, Object> attributes, Broker<?> broker) { - super(parentsMap(broker),attributes); + super(attributes, broker); } @Override @@ -55,24 +53,14 @@ public class BrokerConsoleLoggerImpl ext @Override public Appender<ILoggingEvent> asAppender() { - ch.qos.logback.classic.Logger rootLogger = - (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>(); + initializeAppender(consoleAppender); final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); encoder.setPattern(getLayout()); - encoder.setContext(rootLogger.getLoggerContext()); + encoder.setContext(consoleAppender.getContext()); encoder.start(); - ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>(); - consoleAppender.setContext(rootLogger.getLoggerContext()); - - for(BrokerLoggerFilter<?> filter : getChildren(BrokerLoggerFilter.class)) - { - consoleAppender.addFilter(filter.asFilter()); - } - consoleAppender.addFilter(DenyAllFilter.getInstance()); - consoleAppender.setName(getName()); - consoleAppender.setEncoder(encoder); consoleAppender.start(); Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java Tue Jun 9 11:14:07 2015 @@ -27,6 +27,7 @@ import ch.qos.logback.classic.LoggerCont import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.Appender; +import ch.qos.logback.core.Context; import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP; @@ -35,13 +36,11 @@ import ch.qos.logback.core.rolling.TimeB import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.BrokerLoggerFilter; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; -public class BrokerFileLoggerImpl extends AbstractConfiguredObject<BrokerFileLoggerImpl> implements BrokerFileLogger<BrokerFileLoggerImpl> +public class BrokerFileLoggerImpl extends AbstractBrokerLogger<BrokerFileLoggerImpl> implements BrokerFileLogger<BrokerFileLoggerImpl> { @ManagedAttributeField private String _layout; @@ -63,7 +62,7 @@ public class BrokerFileLoggerImpl extend @ManagedObjectFactoryConstructor protected BrokerFileLoggerImpl(final Map<String, Object> attributes, Broker<?> broker) { - super(parentsMap(broker),attributes); + super(attributes, broker); } @Override @@ -117,20 +116,12 @@ public class BrokerFileLoggerImpl extend @Override public Appender<ILoggingEvent> asAppender() { - ch.qos.logback.classic.Logger rootLogger = - (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - LoggerContext loggerContext = rootLogger.getLoggerContext(); RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>(); appender.setFile(getFileName()); appender.setAppend(true); - appender.setContext(loggerContext); - for(BrokerLoggerFilter<?> filter : getChildren(BrokerLoggerFilter.class)) - { - appender.addFilter(filter.asFilter()); - } - appender.addFilter(DenyAllFilter.getInstance()); - appender.setName(getName()); + initializeAppender(appender); + Context loggerContext = appender.getContext(); if(isRollDaily()) { Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerMemoryLoggerImpl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerMemoryLoggerImpl.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerMemoryLoggerImpl.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerMemoryLoggerImpl.java Tue Jun 9 11:14:07 2015 @@ -28,13 +28,11 @@ import ch.qos.logback.core.Appender; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.BrokerLoggerFilter; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; -public class BrokerMemoryLoggerImpl extends AbstractConfiguredObject<BrokerMemoryLoggerImpl> implements BrokerMemoryLogger<BrokerMemoryLoggerImpl> +public class BrokerMemoryLoggerImpl extends AbstractBrokerLogger<BrokerMemoryLoggerImpl> implements BrokerMemoryLogger<BrokerMemoryLoggerImpl> { @ManagedAttributeField @@ -43,7 +41,7 @@ public class BrokerMemoryLoggerImpl exte @ManagedObjectFactoryConstructor protected BrokerMemoryLoggerImpl(final Map<String, Object> attributes, Broker<?> broker) { - super(parentsMap(broker),attributes); + super(attributes, broker); } @Override @@ -55,19 +53,8 @@ public class BrokerMemoryLoggerImpl exte @Override public Appender<ILoggingEvent> asAppender() { - ch.qos.logback.classic.Logger rootLogger = - (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - LoggerContext loggerContext = rootLogger.getLoggerContext(); - final RecordEventAppender appender = new RecordEventAppender(getMaxRecords()); - appender.setName(getName()); - appender.setContext(loggerContext); - - for(BrokerLoggerFilter<?> filter : getChildren(BrokerLoggerFilter.class)) - { - appender.addFilter(filter.asFilter()); - } - appender.addFilter(DenyAllFilter.getInstance()); + initializeAppender(appender); appender.start(); return appender; } Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilter.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilter.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilter.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilter.java Tue Jun 9 11:14:07 2015 @@ -29,6 +29,8 @@ public interface BrokerNameAndLevelFilte { String TYPE = "NameAndLevel"; + String LOGGER_NAME = "loggerName"; + String LEVEL = "level"; @ManagedAttribute( defaultValue = "" ) String getLoggerName(); Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterImpl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterImpl.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterImpl.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterImpl.java Tue Jun 9 11:14:07 2015 @@ -21,6 +21,7 @@ package org.apache.qpid.server.logging; import java.util.Map; +import java.util.Set; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -28,20 +29,28 @@ import ch.qos.logback.classic.spi.ILoggi import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.BrokerLogger; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.StateTransition; public class BrokerNameAndLevelFilterImpl extends AbstractConfiguredObject<BrokerNameAndLevelFilterImpl> implements BrokerNameAndLevelFilter<BrokerNameAndLevelFilterImpl> { @ManagedAttributeField private String _loggerName; - @ManagedAttributeField + @ManagedAttributeField(afterSet = "logLevelAfterSet") private LogLevel _level; + private volatile Level _logbackLevel; + @ManagedObjectFactoryConstructor protected BrokerNameAndLevelFilterImpl(final Map<String, Object> attributes, BrokerLogger<?> logger) { @@ -49,6 +58,19 @@ public class BrokerNameAndLevelFilterImp } @Override + protected void validateChange(ConfiguredObject<?> proxyForValidation, Set<String> changedAttributes) + { + super.validateChange(proxyForValidation, changedAttributes); + BrokerNameAndLevelFilter proxyFilter = (BrokerNameAndLevelFilter)proxyForValidation; + if (changedAttributes.contains(LOGGER_NAME) && + ((getLoggerName() != null && !getLoggerName().equals(proxyFilter.getLoggerName())) || + (getLoggerName() == null && proxyFilter.getLoggerName() != null))) + { + throw new IllegalConfigurationException("Attribute '" + LOGGER_NAME + " cannot be changed"); + } + } + + @Override public String getLoggerName() { return _loggerName; @@ -60,10 +82,14 @@ public class BrokerNameAndLevelFilterImp return _level; } + private void logLevelAfterSet() + { + _logbackLevel = Level.toLevel(getLevel().name()); + } + @Override public Filter<ILoggingEvent> asFilter() { - final Level level = Level.toLevel(getLevel().name()); final String loggerName = getLoggerName(); if("".equals(loggerName) || Logger.ROOT_LOGGER_NAME.equals(loggerName)) { @@ -72,7 +98,7 @@ public class BrokerNameAndLevelFilterImp @Override public FilterReply decide(final ILoggingEvent event) { - return event.getLevel().isGreaterOrEqual(level) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; + return event.getLevel().isGreaterOrEqual(_logbackLevel) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; } }; } @@ -84,7 +110,7 @@ public class BrokerNameAndLevelFilterImp @Override public FilterReply decide(final ILoggingEvent event) { - return event.getLevel().isGreaterOrEqual(level) && event.getLoggerName().startsWith(prefixName) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; + return event.getLevel().isGreaterOrEqual(_logbackLevel) && event.getLoggerName().startsWith(prefixName) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; } }; } @@ -95,9 +121,33 @@ public class BrokerNameAndLevelFilterImp @Override public FilterReply decide(final ILoggingEvent event) { - return event.getLevel().isGreaterOrEqual(level) && event.getLoggerName().equals(loggerName) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; + return event.getLevel().isGreaterOrEqual(_logbackLevel) && event.getLoggerName().equals(loggerName) ? FilterReply.ACCEPT : FilterReply.NEUTRAL; } }; } } + + @StateTransition( currentState = { State.ACTIVE, State.ERRORED, State.UNINITIALIZED }, desiredState = State.DELETED ) + private ListenableFuture<Void> doDelete() + { + final SettableFuture<Void> returnVal = SettableFuture.create(); + closeAsync().addListener(new Runnable() + { + @Override + public void run() + { + setState(State.DELETED); + returnVal.set(null); + + } + }, getTaskExecutor().getExecutor()); + return returnVal; + } + + @StateTransition( currentState = { State.ERRORED, State.UNINITIALIZED }, desiredState = State.ACTIVE ) + private ListenableFuture<Void> doActivate() + { + setState(State.ACTIVE); + return Futures.immediateFuture(null); + } } Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/CompositeFilter.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/CompositeFilter.java?rev=1684380&view=auto ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/CompositeFilter.java (added) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/CompositeFilter.java Tue Jun 9 11:14:07 2015 @@ -0,0 +1,79 @@ +/* + * + * 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.qpid.server.logging; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.Filter; +import ch.qos.logback.core.spi.FilterReply; +import org.apache.qpid.server.model.BrokerLoggerFilter; + +public class CompositeFilter extends Filter<ILoggingEvent> +{ + private List<Filter<ILoggingEvent>> _filterList = new CopyOnWriteArrayList<>(); + + public void addFilter(BrokerLoggerFilter filter) + { + Filter f = filter.asFilter(); + f.setName(filter.getName()); + _filterList.add(f); + } + + public void addFilters(Collection<BrokerLoggerFilter> filters) + { + for(BrokerLoggerFilter<?> filter : filters) + { + addFilter(filter); + } + } + + public void removeFilter(BrokerLoggerFilter filter) + { + Iterator<Filter<ILoggingEvent>> it = _filterList.iterator(); + while(it.hasNext()) + { + Filter f = it.next(); + if (f.getName().equals(filter.getName())) + { + _filterList.remove(f); + break; + } + } + } + + @Override + public FilterReply decide(ILoggingEvent event) + { + for(Filter filter : _filterList) + { + FilterReply reply = filter.decide(event); + if (reply == FilterReply.DENY || reply == FilterReply.ACCEPT) + { + return reply; + } + } + return FilterReply.DENY; + } +} Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java Tue Jun 9 11:14:07 2015 @@ -32,7 +32,6 @@ import java.security.AccessController; import java.security.Principal; import java.util.Collection; import java.util.Collections; -import java.util.EnumSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -42,6 +41,7 @@ import javax.security.auth.Subject; import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.Binding; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerLoggerFilter; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Connection; import org.apache.qpid.server.model.Consumer; @@ -365,7 +365,7 @@ public class SecurityManager // CREATE GROUP MEMBER is transformed into UPDATE GROUP rule return Operation.UPDATE; } - else if (isBrokerOrBrokerChildOrPreferencesProvider(category)) + else if (isBrokerType(category)) { // CREATE/UPDATE broker child is transformed into CONFIGURE BROKER rule return Operation.CONFIGURE; @@ -378,7 +378,7 @@ public class SecurityManager // DELETE BINDING is transformed into UNBIND EXCHANGE rule return Operation.UNBIND; } - else if (isBrokerOrBrokerChildOrPreferencesProvider(category)) + else if (isBrokerType(category)) { // DELETE broker child is transformed into CONFIGURE BROKER rule return Operation.CONFIGURE; @@ -393,10 +393,11 @@ public class SecurityManager return operation; } - private boolean isBrokerOrBrokerChildOrPreferencesProvider(Class<? extends ConfiguredObject> category) + private boolean isBrokerType(Class<? extends ConfiguredObject> category) { return Broker.class.isAssignableFrom(category) || PreferencesProvider.class.isAssignableFrom(category) || + BrokerLoggerFilter.class.isAssignableFrom(category) || ( !VirtualHostNode.class.isAssignableFrom(category) && getModel().getChildTypes(Broker.class).contains(category)); } @@ -438,7 +439,7 @@ public class SecurityManager Queue<?> queue = (Queue<?>)configuredObject.getParent(Queue.class); setQueueProperties(queue, properties); } - else if (isBrokerOrBrokerChildOrPreferencesProvider(configuredObjectType)) + else if (isBrokerType(configuredObjectType)) { String description = String.format("%s %s '%s'", configuredObjectOperation == null? null : configuredObjectOperation.name().toLowerCase(), @@ -484,7 +485,7 @@ public class SecurityManager { return ObjectType.VIRTUALHOSTNODE; } - else if (isBrokerOrBrokerChildOrPreferencesProvider(category)) + else if (isBrokerType(category)) { return ObjectType.BROKER; } Added: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerLoggerTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerLoggerTest.java?rev=1684380&view=auto ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerLoggerTest.java (added) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerLoggerTest.java Tue Jun 9 11:14:07 2015 @@ -0,0 +1,188 @@ +/* + * + * 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.qpid.server.logging; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.read.ListAppender; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutorImpl; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerLoggerFilter; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.test.utils.QpidTestCase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BrokerLoggerTest extends QpidTestCase +{ + + private AbstractBrokerLogger<?> _brokerLogger; + private ListAppender _loggerAppender; + private TaskExecutor _taskExecutor; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _loggerAppender = new ListAppender(); + + ch.qos.logback.classic.Logger rootLogger = + (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + rootLogger.addAppender(_loggerAppender); + + _taskExecutor = new TaskExecutorImpl(); + _taskExecutor.start(); + + Model model = BrokerModel.getInstance(); + + org.apache.qpid.server.security.SecurityManager securityManager = mock(SecurityManager.class); + Broker<?> broker = mock(Broker.class); + when(broker.getSecurityManager()).thenReturn(securityManager); + when(broker.getModel()).thenReturn(model); + when(broker.getChildExecutor()).thenReturn(_taskExecutor); + doReturn(Broker.class).when(broker).getCategoryClass(); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put("name", "test"); + _brokerLogger = new AbstractBrokerLogger(attributes, broker) + { + @Override + public Appender<ILoggingEvent> asAppender() + { + return _loggerAppender; + } + }; + _brokerLogger.open(); + _loggerAppender.addFilter(_brokerLogger.getCompositeFilter()); + } + + @Override + public void tearDown() throws Exception + { + try + { + _taskExecutor.stopImmediately(); + + ch.qos.logback.classic.Logger rootLogger = + (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + + _loggerAppender.clearAllFilters(); + + _loggerAppender.stop(); + rootLogger.detachAppender(_loggerAppender); + } + finally + { + super.tearDown(); + } + } + + public void testAddNewFilter() + { + Map<String, Object> attributes = new HashMap<>(); + attributes.put("loggerName", "org.apache.qpid"); + attributes.put("level", LogLevel.INFO); + attributes.put("name", "test"); + attributes.put("type", BrokerNameAndLevelFilter.TYPE); + + Collection<BrokerLoggerFilter> filtersBefore = _brokerLogger.getChildren(BrokerLoggerFilter.class); + assertEquals("Unexpected number of filters before creation", 0, filtersBefore.size()); + + BrokerLoggerFilter<?> createdFilter = _brokerLogger.createChild(BrokerLoggerFilter.class, attributes); + assertEquals("Unexpected filter name", "test", createdFilter.getName()); + + Collection<BrokerLoggerFilter> filtersAfter = _brokerLogger.getChildren(BrokerLoggerFilter.class); + assertEquals("Unexpected number of filters after creation", 1, filtersAfter.size()); + + BrokerLoggerFilter filter = filtersAfter.iterator().next(); + assertEquals("Unexpected filter", createdFilter, filter); + + Logger logger = LoggerFactory.getLogger("org.apache.qpid"); + + _loggerAppender.start(); + logger.debug("Test2"); + logger.info("Test3"); + _loggerAppender.stop(); + + assertLoggedEvent(false, "Test2", logger.getName(), Level.DEBUG); + assertLoggedEvent(true, "Test3", logger.getName(), Level.INFO); + } + + public void testRemoveExistingFilter() + { + Map<String, Object> attributes = new HashMap<>(); + attributes.put("loggerName", "org.apache.qpid"); + attributes.put("level", LogLevel.INFO); + attributes.put("name", "test"); + attributes.put("type", BrokerNameAndLevelFilter.TYPE); + BrokerLoggerFilter<?> createdFilter = _brokerLogger.createChild(BrokerLoggerFilter.class, attributes); + Logger logger = LoggerFactory.getLogger("org.apache.qpid"); + + _loggerAppender.start(); + logger.info("Test1"); + _loggerAppender.stop(); + + assertLoggedEvent(true, "Test1", logger.getName(), Level.INFO); + + createdFilter.delete(); + + _loggerAppender.start(); + logger.info("Test2"); + _loggerAppender.stop(); + + assertLoggedEvent(false, "Test2", logger.getName(), Level.INFO); + } + + private void assertLoggedEvent(boolean exists, String message, String loggerName, Level level) + { + List<ILoggingEvent> events; + synchronized(_loggerAppender) + { + events = new ArrayList<>(_loggerAppender.list); + } + + boolean logged = false; + for (ILoggingEvent event: events) + { + if (event.getFormattedMessage().equals(message) && event.getLoggerName().equals(loggerName) && event.getLevel() == level) + { + logged = true; + break; + } + } + assertEquals("Event " + message + " from logger " + loggerName + " of log level " + level + + " is " + (exists ? "not" : "") + " found", exists, logged); + } +} Added: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterTest.java?rev=1684380&view=auto ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterTest.java (added) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerNameAndLevelFilterTest.java Tue Jun 9 11:14:07 2015 @@ -0,0 +1,207 @@ +/* + * + * 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.qpid.server.logging; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutorImpl; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerLogger; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.test.utils.QpidTestCase; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BrokerNameAndLevelFilterTest extends QpidTestCase +{ + private Logger _logger = null; + private Logger _nonQpidLogger = null; + + private BrokerLogger<?> _brokerLogger; + private BrokerNameAndLevelFilter<?> _brokerNameAndLevelFilter; + private ListAppender _loggerAppender; + private TaskExecutor _taskExecutor; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _loggerAppender = new ListAppender(); + + _taskExecutor = new TaskExecutorImpl(); + _taskExecutor.start(); + + Model model = BrokerModel.getInstance(); + + SecurityManager securityManager = mock(SecurityManager.class); + Broker<?> broker = mock(Broker.class); + when(broker.getSecurityManager()).thenReturn(securityManager); + when(broker.getModel()).thenReturn(model); + doReturn(Broker.class).when(broker).getCategoryClass(); + + _brokerLogger = mock(BrokerLogger.class); + when(_brokerLogger.getModel()).thenReturn(model); + when(_brokerLogger.getChildExecutor()).thenReturn(_taskExecutor); + when(_brokerLogger.getParent(Broker.class)).thenReturn(broker); + doReturn(BrokerLogger.class).when(_brokerLogger).getCategoryClass(); + + + _logger = LoggerFactory.getLogger("org.apache.qpid.server.test"); + _nonQpidLogger = LoggerFactory.getLogger("org.apache.qpid.test"); + } + + private void setUpFilterAndAppender(String loggerName, LogLevel logLevel) + { + Map<String, Object> attributes = new HashMap<>(); + attributes.put("loggerName", loggerName); + attributes.put("level", logLevel); + attributes.put("name", "test"); + + _brokerNameAndLevelFilter = new BrokerNameAndLevelFilterImplFactory().createInstance(attributes, _brokerLogger); + _brokerNameAndLevelFilter.open(); + ch.qos.logback.classic.Logger rootLogger = + (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + rootLogger.addAppender(_loggerAppender); + _loggerAppender.setContext(rootLogger.getLoggerContext()); + _loggerAppender.addFilter(_brokerNameAndLevelFilter.asFilter()); + _loggerAppender.addFilter(DenyAllFilter.getInstance()); + } + + @Override + public void tearDown() throws Exception + { + try + { + _brokerNameAndLevelFilter.close(); + _taskExecutor.stopImmediately(); + + ch.qos.logback.classic.Logger rootLogger = + (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + + _loggerAppender.clearAllFilters(); + + _loggerAppender.stop(); + rootLogger.detachAppender(_loggerAppender); + } + finally + { + super.tearDown(); + } + } + + public void testSetNameOnWildcardFilter() throws Exception + { + setUpFilterAndAppender("org.apache.qpid.server.*", LogLevel.DEBUG); + _loggerAppender.start(); + _logger.debug("Test1"); + _nonQpidLogger.debug("Test2"); + _loggerAppender.stop(); + + assertLoggedEvent(true, "Test1", _logger.getName(), Level.DEBUG); + assertLoggedEvent(false, "Test2", _nonQpidLogger.getName(), Level.DEBUG); + + try + { + _brokerNameAndLevelFilter.setAttributes(Collections.<String, Object>singletonMap("loggerName", "org.apache.qpid.*")); + fail("Changing of logger name is unsupported"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } + + public void testSetLevelOnWildcardFilter() throws Exception + { + setUpFilterAndAppender("org.apache.qpid.server.*", LogLevel.DEBUG); + doChangeLevelTest(); + } + + public void testSetLevelOnEmptyLogNameFilter() throws Exception + { + setUpFilterAndAppender("", LogLevel.DEBUG); + doChangeLevelTest(); + } + + public void testSetLevelOnNonEmptyAndNonWildCardLogNameFilter() throws Exception + { + setUpFilterAndAppender(_logger.getName(), LogLevel.DEBUG); + doChangeLevelTest(); + } + + private void doChangeLevelTest() + { + _loggerAppender.start(); + _logger.debug("Test1"); + _loggerAppender.stop(); + + assertLoggedEvent(true, "Test1", _logger.getName(), Level.DEBUG); + + _brokerNameAndLevelFilter.setAttributes(Collections.<String, Object>singletonMap("level", LogLevel.INFO)); + assertEquals("Unexpected log level attribute", LogLevel.INFO, _brokerNameAndLevelFilter.getLevel()); + + _loggerAppender.start(); + _logger.debug("Test2"); + _logger.info("Test3"); + _loggerAppender.stop(); + + assertLoggedEvent(false, "Test2", _logger.getName(), Level.DEBUG); + assertLoggedEvent(true, "Test3", _logger.getName(), Level.INFO); + } + + private void assertLoggedEvent(boolean exists, String message, String loggerName, Level level) + { + List<ILoggingEvent> events; + synchronized(_loggerAppender) + { + events = new ArrayList<>(_loggerAppender.list); + } + + boolean logged = false; + for (ILoggingEvent event: events) + { + if (event.getFormattedMessage().equals(message) && event.getLoggerName().equals(loggerName) && event.getLevel() == level) + { + logged = true; + break; + } + } + assertEquals("Event " + message + " from logger " + loggerName + " of log level " + level + + " is " + (exists ? "not" : "") + " found", exists, logged); + } + +} Added: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/CompositeFilterTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/CompositeFilterTest.java?rev=1684380&view=auto ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/CompositeFilterTest.java (added) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/CompositeFilterTest.java Tue Jun 9 11:14:07 2015 @@ -0,0 +1,157 @@ +/* + * + * 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.qpid.server.logging; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.Filter; +import ch.qos.logback.core.spi.FilterReply; +import org.apache.qpid.server.model.BrokerLoggerFilter; +import org.apache.qpid.test.utils.QpidTestCase; + +public class CompositeFilterTest extends QpidTestCase +{ + public void testDecideWithNoFilterAdded() + { + CompositeFilter compositeFilter = new CompositeFilter(); + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply with no filter added", FilterReply.DENY, reply); + } + + public void testDecideWithAcceptFilter() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + compositeFilter.addFilter(createBrokerFilter(FilterReply.ACCEPT)); + + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply with ACCEPT filter added", FilterReply.ACCEPT, reply); + } + + public void testDecideWithNeutralFilter() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + compositeFilter.addFilter(createBrokerFilter(FilterReply.NEUTRAL)); + + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply with NEUTRAL filter added", FilterReply.DENY, reply); + } + + public void testDecideWithFilterChain() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + BrokerLoggerFilter brokerFilterNeutral = createBrokerFilter(FilterReply.NEUTRAL); + compositeFilter.addFilter(brokerFilterNeutral); + + BrokerLoggerFilter brokerFilterDeny = createBrokerFilter(FilterReply.DENY); + compositeFilter.addFilter(brokerFilterDeny); + + BrokerLoggerFilter brokerFilterAccept = createBrokerFilter(FilterReply.ACCEPT); + compositeFilter.addFilter(brokerFilterAccept); + + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply", FilterReply.DENY, reply); + + verify(brokerFilterNeutral.asFilter()).decide(any()); + verify(brokerFilterDeny.asFilter()).decide(any()); + verify(brokerFilterAccept.asFilter(), never()).decide(any()); + } + + public void testRemoveFilterFromChain() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + BrokerLoggerFilter brokerFilterNeutral = createBrokerFilter(FilterReply.NEUTRAL, "neutral"); + compositeFilter.addFilter(brokerFilterNeutral); + + BrokerLoggerFilter brokerFilterDeny = createBrokerFilter(FilterReply.DENY, "deny"); + compositeFilter.addFilter(brokerFilterDeny); + + BrokerLoggerFilter brokerFilterAccept = createBrokerFilter(FilterReply.ACCEPT, "accept"); + compositeFilter.addFilter(brokerFilterAccept); + + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply", FilterReply.DENY, reply); + + compositeFilter.removeFilter(brokerFilterDeny); + + FilterReply reply2 = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply", FilterReply.ACCEPT, reply2); + + verify(brokerFilterNeutral.asFilter(), times(2)).decide(any()); + verify(brokerFilterDeny.asFilter()).decide(any()); + verify(brokerFilterAccept.asFilter()).decide(any()); + } + + public void testAddFilter() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + BrokerLoggerFilter brokerFilter = createBrokerFilter(FilterReply.ACCEPT, "accept"); + compositeFilter.addFilter(brokerFilter); + + verify(brokerFilter.asFilter()).setName("accept"); + } + + public void testAddFilters() + { + CompositeFilter compositeFilter = new CompositeFilter(); + + BrokerLoggerFilter brokerFilterNeutral = createBrokerFilter(FilterReply.NEUTRAL, "neutral"); + BrokerLoggerFilter brokerFilterAccept = createBrokerFilter(FilterReply.ACCEPT, "accept"); + BrokerLoggerFilter brokerFilterDeny = createBrokerFilter(FilterReply.DENY, "deny"); + + compositeFilter.addFilters(Arrays.asList(brokerFilterNeutral, brokerFilterAccept, brokerFilterDeny)); + + FilterReply reply = compositeFilter.decide(mock(ILoggingEvent.class)); + assertEquals("Unexpected reply", FilterReply.ACCEPT, reply); + + verify(brokerFilterNeutral.asFilter()).decide(any()); + verify(brokerFilterAccept.asFilter()).decide(any()); + verify(brokerFilterDeny.asFilter(), never()).decide(any()); + } + + private BrokerLoggerFilter createBrokerFilter(FilterReply decision) + { + return createBrokerFilter(decision, "UNNAMED"); + } + + private BrokerLoggerFilter createBrokerFilter(final FilterReply decision, String name) + { + BrokerLoggerFilter brokerFilter = mock(BrokerLoggerFilter.class); + when(brokerFilter.getName()).thenReturn(name); + Filter filter = mock(Filter.class); + when(filter.getName()).thenReturn(name); + when(filter.decide(any())).thenReturn(decision); + when(brokerFilter.asFilter()).thenReturn(filter); + return brokerFilter; + } +} Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java (original) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java Tue Jun 9 11:14:07 2015 @@ -36,6 +36,8 @@ import org.apache.qpid.server.model.Acce import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Binding; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerLogger; +import org.apache.qpid.server.model.BrokerLoggerFilter; import org.apache.qpid.server.model.BrokerModel; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Consumer; @@ -273,7 +275,7 @@ public class SecurityManagerTest extends when(exchange.getCategoryClass()).thenReturn(Exchange.class); when(exchange.getParent(VirtualHost.class)).thenReturn(vh); - assertCreateAuthorization( exchange, Operation.CREATE, ObjectType.EXCHANGE, expectedProperties, vh); + assertCreateAuthorization(exchange, Operation.CREATE, ObjectType.EXCHANGE, expectedProperties, vh); } public void testAuthoriseCreateQueue() @@ -815,6 +817,32 @@ public class SecurityManagerTest extends assertDeleteAuthorization(binding, Operation.UNBIND, ObjectType.EXCHANGE, properties, exchange, queue); } + public void testAuthoriseBrokerLoggerOperations() + { + BrokerLogger mock = mock(BrokerLogger.class); + when(mock.getAttribute(ConfiguredObject.NAME)).thenReturn("TEST"); + when(mock.getCategoryClass()).thenReturn(BrokerLogger.class); + when(mock.getParent(Broker.class)).thenReturn(_broker); + assertBrokerChildCreateAuthorization(mock); + + when(mock.getAttribute(ConfiguredObject.NAME)).thenReturn("test"); + assertBrokerChildUpdateAuthorization(mock); + assertBrokerChildDeleteAuthorization(mock); + } + + public void testAuthoriseBrokerLoggerFilterOperations() + { + BrokerLoggerFilter mock = mock(BrokerLoggerFilter.class); + when(mock.getAttribute(ConfiguredObject.NAME)).thenReturn("TEST"); + when(mock.getCategoryClass()).thenReturn(BrokerLogger.class); + when(mock.getParent(Broker.class)).thenReturn(_broker); + assertBrokerChildCreateAuthorization(mock); + + when(mock.getAttribute(ConfiguredObject.NAME)).thenReturn("test"); + assertBrokerChildUpdateAuthorization(mock); + assertBrokerChildDeleteAuthorization(mock); + } + private VirtualHost getMockVirtualHost() { VirtualHost vh = mock(VirtualHost.class); Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java (original) +++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java Tue Jun 9 11:14:07 2015 @@ -323,6 +323,9 @@ public class HttpManagement extends Abst addRestServlet(root, "binding", VirtualHostNode.class, VirtualHost.class, Exchange.class, Queue.class, Binding.class); addRestServlet(root, "session", VirtualHostNode.class, VirtualHost.class, Connection.class, Session.class); + addRestServlet(root, "brokerlogger", BrokerLogger.class); + addRestServlet(root, "brokerloggerfilter", BrokerLogger.class, BrokerLoggerFilter.class); + ServletHolder apiDocsServlet = new ServletHolder(new ApiDocsServlet(getModel(), Collections.<String>emptyList())); root.addServlet(apiDocsServlet, "/apidocs"); root.addServlet(apiDocsServlet, "/apidocs/"); Modified: qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java?rev=1684380&r1=1684379&r2=1684380&view=diff ============================================================================== --- qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java (original) +++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java Tue Jun 9 11:14:07 2015 @@ -29,7 +29,9 @@ import java.util.Map; import javax.servlet.http.HttpServletResponse; +import org.apache.qpid.server.logging.BrokerNameAndLevelFilter; import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet; +import org.apache.qpid.server.model.ConfiguredObject; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.apache.qpid.server.management.plugin.HttpManagement; @@ -832,6 +834,74 @@ public class BrokerACLTest extends QpidR details.get(HttpManagement.HTTPS_SASL_AUTHENTICATION_ENABLED)); } + /* === Broker Logger Filters === */ + + public void testCreateBrokerLoggerFilterAllowedDenied() throws Exception + { + getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); + + getRestTestHelper().submitRequest("brokerloggerfilter/memory/1", "GET", HttpServletResponse.SC_OK); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(BrokerNameAndLevelFilter.NAME, "2"); + attributes.put(ConfiguredObject.TYPE, BrokerNameAndLevelFilter.TYPE); + attributes.put(BrokerNameAndLevelFilter.LEVEL, "DEBUG"); + + getRestTestHelper().submitRequest("brokerloggerfilter/memory", "PUT", attributes, HttpServletResponse.SC_CREATED); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "GET", HttpServletResponse.SC_OK); + + getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); + attributes.put(BrokerNameAndLevelFilter.NAME, "3"); + getRestTestHelper().submitRequest("brokerloggerfilter/memory", "PUT", attributes, HttpServletResponse.SC_FORBIDDEN); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/3", "GET", HttpServletResponse.SC_NOT_FOUND); + } + + public void testUpdateBrokerLoggerFilterAllowedDenied() throws Exception + { + getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); + + Map<String,Object> result = getRestTestHelper().getJsonAsSingletonList("brokerloggerfilter/memory/1"); + assertEquals("Log level was not as expected", "INFO", result.get(BrokerNameAndLevelFilter.LEVEL)); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(BrokerNameAndLevelFilter.NAME, "1"); + attributes.put(ConfiguredObject.TYPE, BrokerNameAndLevelFilter.TYPE); + attributes.put(BrokerNameAndLevelFilter.LEVEL, "DEBUG"); + + getRestTestHelper().submitRequest("brokerloggerfilter/memory/1", "PUT", attributes, HttpServletResponse.SC_OK); + Map<String,Object> resultAfterUpdate = getRestTestHelper().getJsonAsSingletonList("brokerloggerfilter/memory/1"); + assertEquals("Log level was not changed", "DEBUG", resultAfterUpdate.get(BrokerNameAndLevelFilter.LEVEL)); + + + getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); + attributes.put(BrokerNameAndLevelFilter.LEVEL, "INFO"); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/1", "PUT", attributes, HttpServletResponse.SC_FORBIDDEN); + + Map<String,Object> resultAfterDeniedUpdate = getRestTestHelper().getJsonAsSingletonList("brokerloggerfilter/memory/1"); + assertEquals("Log level was changed by not allowed user", "DEBUG", resultAfterDeniedUpdate.get(BrokerNameAndLevelFilter.LEVEL)); + } + + public void testDeleteBrokerLoggerFilterAllowedDenied() throws Exception + { + getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(BrokerNameAndLevelFilter.NAME, "2"); + attributes.put(ConfiguredObject.TYPE, BrokerNameAndLevelFilter.TYPE); + attributes.put(BrokerNameAndLevelFilter.LEVEL, "DEBUG"); + + getRestTestHelper().submitRequest("brokerloggerfilter/memory", "PUT", attributes, HttpServletResponse.SC_CREATED); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "GET", HttpServletResponse.SC_OK); + + getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "DELETE", null, HttpServletResponse.SC_FORBIDDEN); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "GET", HttpServletResponse.SC_OK); + + getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "DELETE", null, HttpServletResponse.SC_OK); + getRestTestHelper().submitRequest("brokerloggerfilter/memory/2", "GET", HttpServletResponse.SC_NOT_FOUND); + } + /* === Utility Methods === */ private int createPort(String portName) throws Exception --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org