summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorAlex Rudyy <orudyy@apache.org>2013-05-03 11:20:54 +0000
committerAlex Rudyy <orudyy@apache.org>2013-05-03 11:20:54 +0000
commitfbb001cd7891b6ea719a7186fe9f75fbd7a5cbfd (patch)
treee72e34836ce77807feef7559b3556861d4f7bd3a /java
parent3273d0ffe760cd48300f1b8cad4a43347a0b7dca (diff)
downloadqpid-python-fbb001cd7891b6ea719a7186fe9f75fbd7a5cbfd.tar.gz
QPID-4802: In management mode set state to ERRORED for failing to activate authentication providers, group providers and acl providers in order to allow editing of attributes preventing normal startup
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1478731 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java')
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AccessControlProvider.js2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js11
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js19
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Port.js2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showAccessControlProvider.html2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showPort.html19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java23
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java23
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java72
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java4
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java245
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java31
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java98
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java33
19 files changed, 620 insertions, 62 deletions
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AccessControlProvider.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AccessControlProvider.js
index fd8a3ecb0e..9d9343623b 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AccessControlProvider.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AccessControlProvider.js
@@ -100,6 +100,7 @@ define(["dojo/_base/xhr",
this.controller = controller;
this.name = query(".name", node)[0];
this.type = query(".type", node)[0];
+ this.state = query(".state", node)[0];
this.query = "rest/accesscontrolprovider/"+encodeURIComponent(groupProviderObj.name);
var that = this;
@@ -125,6 +126,7 @@ define(["dojo/_base/xhr",
{
this.name.innerHTML = this.accessControlProviderData[ "name" ];
this.type.innerHTML = this.accessControlProviderData[ "type" ];
+ this.state.innerHTML = this.accessControlProviderData[ "state" ];
};
return AccessControlProvider;
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
index b7c0554158..4778671bda 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
@@ -115,11 +115,9 @@ define(["dojo/_base/xhr",
this.controller = controller;
this.name = query(".name", node)[0];
this.type = query(".type", node)[0];
+ this.state = query(".state", node)[0];
this.authenticationProvider = authenticationProvider;
- /*this.state = dom.byId("state");
- this.durable = dom.byId("durable");
- this.lifetimePolicy = dom.byId("lifetimePolicy");
- */
+
this.query = "rest/authenticationprovider/" + encodeURIComponent(authProviderObj.name);
var that = this;
@@ -155,10 +153,7 @@ define(["dojo/_base/xhr",
this.authenticationProvider.name = this.authProviderData[ "name" ]
this.name.innerHTML = this.authProviderData[ "name" ];
this.type.innerHTML = this.authProviderData[ "type" ];
- /* this.state.innerHTML = this.brokerData[ "state" ];
- this.durable.innerHTML = this.brokerData[ "durable" ];
- this.lifetimePolicy.innerHTML = this.brokerData[ "lifetimePolicy" ];
-*/
+ this.state.innerHTML = this.authProviderData[ "state" ];
};
AuthProviderUpdater.prototype.update = function()
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
index 230f148d4c..9074c1b43c 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
@@ -576,14 +576,15 @@ define(["dojo/_base/xhr",
that.authenticationProvidersGrid =
new UpdatableStore(that.brokerData.authenticationproviders, query(".broker-authentication-providers")[0],
- [ { name: "Name", field: "name", width: "100%"},
- { name: "Type", field: "type", width: "300px"},
- { name: "User Management", field: "type", width: "200px",
+ [ { name: "Name", field: "name", width: "30%"},
+ { name: "State", field: "state", width: "20%"},
+ { name: "Type", field: "type", width: "20%"},
+ { name: "User Management", field: "type", width: "20%",
formatter: function(val){
return "<input type='radio' disabled='disabled' "+(util.isProviderManagingUsers(val)?"checked='checked'": "")+" />";
}
},
- { name: "Default", field: "name", width: "100px",
+ { name: "Default", field: "name", width: "10%",
formatter: function(val){
return "<input type='radio' disabled='disabled' "+(val == that.brokerData.defaultAuthenticationProvider ? "checked='checked'": "")+" />";
}
@@ -637,8 +638,9 @@ define(["dojo/_base/xhr",
}, gridProperties, EnhancedGrid);
that.groupProvidersGrid =
new UpdatableStore(that.brokerData.groupproviders, query(".broker-group-providers")[0],
- [ { name: "Name", field: "name", width: "50%"},
- { name: "Type", field: "type", width: "50%"}
+ [ { name: "Name", field: "name", width: "40%"},
+ { name: "State", field: "state", width: "30%"},
+ { name: "Type", field: "type", width: "30%"}
], function(obj) {
connect.connect(obj.grid, "onRowDblClick", obj.grid,
function(evt){
@@ -651,8 +653,9 @@ define(["dojo/_base/xhr",
var aclData = that.brokerData.accesscontrolproviders ? that.brokerData.accesscontrolproviders :[];
that.accessControlProvidersGrid =
new UpdatableStore(aclData, query(".broker-access-control-providers")[0],
- [ { name: "Name", field: "name", width: "60%"},
- { name: "Type", field: "type", width: "40%"}
+ [ { name: "Name", field: "name", width: "40%"},
+ { name: "State", field: "state", width: "30%"},
+ { name: "Type", field: "type", width: "30%"}
], function(obj) {
connect.connect(obj.grid, "onRowDblClick", obj.grid,
function(evt){
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
index 98e01773ef..9dde224982 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
@@ -106,6 +106,7 @@ define(["dojo/_base/xhr",
this.controller = controller;
this.name = query(".name", node)[0];
this.type = query(".type", node)[0];
+ this.state = query(".state", node)[0];
this.query = "rest/groupprovider/"+encodeURIComponent(groupProviderObj.name);
this.typeUI ={"GroupFile": "FileGroupManager"};
var that = this;
@@ -134,6 +135,7 @@ define(["dojo/_base/xhr",
{
this.name.innerHTML = this.groupProviderData[ "name" ];
this.type.innerHTML = this.groupProviderData[ "type" ];
+ this.state.innerHTML = this.groupProviderData[ "state" ];
};
GroupProviderUpdater.prototype.update = function()
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Port.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Port.js
index d1ba4043c2..5d6ce6727b 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Port.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Port.js
@@ -128,6 +128,7 @@ define(["dojo/dom",
}
storeNodes(["nameValue",
+ "stateValue",
"portValue",
"authenticationProviderValue",
"protocolsValue",
@@ -169,6 +170,7 @@ define(["dojo/dom",
}
this.nameValue.innerHTML = this.keyStoreData[ "name" ];
+ this.stateValue.innerHTML = this.keyStoreData[ "state" ];
this.portValue.innerHTML = this.keyStoreData[ "port" ];
this.authenticationProviderValue.innerHTML = this.keyStoreData[ "authenticationProvider" ] ? this.keyStoreData[ "authenticationProvider" ] : "";
this.protocolsValue.innerHTML = printArray( "protocols", this.keyStoreData);
diff --git a/java/broker-plugins/management-http/src/main/java/resources/showAccessControlProvider.html b/java/broker-plugins/management-http/src/main/java/resources/showAccessControlProvider.html
index 399425a7de..d017683225 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/showAccessControlProvider.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/showAccessControlProvider.html
@@ -23,6 +23,8 @@
<br/>
<span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
<br/>
+ <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span>
+ <br/>
<div class="providerDetails"></div>
<div class="dijitDialogPaneActionBar">
<input class="deleteAccessControlProviderButton" type="button" value="Delete Access Control provider" label="Delete Access Control Provider" dojoType="dijit.form.Button" />
diff --git a/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html b/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
index bea5db2829..5e876fdc1f 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
@@ -23,6 +23,8 @@
<br/>
<span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
<br/>
+ <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span>
+ <br/>
<button data-dojo-type="dijit.form.Button" class="editAuthenticationProviderButton">Edit</button>
<button data-dojo-type="dijit.form.Button" class="deleteAuthenticationProviderButton">Delete</button>
</div> \ No newline at end of file
diff --git a/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
index 332c7f5eaa..5ab5573b40 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
@@ -23,6 +23,8 @@
<br/>
<span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
<br/>
+ <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span>
+ <br/>
<div class="providerDetails"></div>
<div class="dijitDialogPaneActionBar">
<input class="deleteGroupProviderButton" type="button" value="Delete Group provider" label="Delete Group Provider" dojoType="dijit.form.Button" />
diff --git a/java/broker-plugins/management-http/src/main/java/resources/showPort.html b/java/broker-plugins/management-http/src/main/java/resources/showPort.html
index f297f2d751..4f460b85c1 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/showPort.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/showPort.html
@@ -18,14 +18,23 @@
- under the License.
-
-->
-<div class="port">
+<div>
<div class="portContainer">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Name:</div>
- <div class="nameValue" style="float:left;"></div><br/>
+ <div class="name" style="clear:both">
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">Name:</div>
+ <div class="nameValue" style="float:left;"></div><br/>
+ </div>
+
+ <div class="state" style="clear:both">
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">State:</div>
+ <div class="stateValue" style="float:left;"></div><br/>
+ </div>
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Port Number:</div>
- <div class="portValue" style="float:left;"></div><br/>
+ <div class="port" style="clear:both">
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">Port Number:</div>
+ <div class="portValue" style="float:left;"></div><br/>
+ </div>
<div class="authenticationProvider" style="clear:both">
<div class="formLabel-labelCell" style="float:left; width: 250px;">Authentication Provider:</div>
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
index abf1537ef7..d08deee29b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
@@ -13,6 +13,8 @@ import org.apache.qpid.server.configuration.ConfigurationEntry;
import org.apache.qpid.server.configuration.ConfigurationEntryStore;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.AccessControlProvider;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.State;
@@ -27,9 +29,12 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore
private static final String PORT_TYPE = Port.class.getSimpleName();
private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName();
private static final String ACCESS_CONTROL_PROVIDER_TYPE = AccessControlProvider.class.getSimpleName();
+ private static final String GROUP_PROVIDER_TYPE = GroupProvider.class.getSimpleName();
+ private static final String AUTHENTICATION_PROVIDER_TYPE = AuthenticationProvider.class.getSimpleName();
private static final String ATTRIBUTE_STATE = VirtualHost.STATE;
private static final Object MANAGEMENT_MODE_AUTH_PROVIDER = "mm-auth";
+
private final ConfigurationEntryStore _store;
private final Map<UUID, ConfigurationEntry> _cliEntries;
private final Map<UUID, Object> _quiescedEntries;
@@ -255,11 +260,7 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore
{
quiesce = true;
}
- else if (ACCESS_CONTROL_PROVIDER_TYPE.equals(entryType))
- {
- quiesce = true;
- }
- else if (PORT_TYPE.equalsIgnoreCase(entryType))
+ else if (PORT_TYPE.equals(entryType))
{
if (attributes == null)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
index 51fd3a5c78..a8c3f54530 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
@@ -351,15 +351,7 @@ abstract class AbstractAdapter implements ConfiguredObject
protected void changeAttributes(final Map<String, Object> attributes)
{
- if (attributes.containsKey(ID))
- {
- UUID id = getId();
- Object idAttributeValue = attributes.get(ID);
- if (idAttributeValue != null && !idAttributeValue.equals(id))
- {
- throw new IllegalConfigurationException("Cannot change existing configured object id");
- }
- }
+ validateChangeAttributes(attributes);
Collection<String> names = getAttributeNames();
for (String name : names)
{
@@ -375,6 +367,19 @@ abstract class AbstractAdapter implements ConfiguredObject
}
}
+ protected void validateChangeAttributes(final Map<String, Object> attributes)
+ {
+ if (attributes.containsKey(ID))
+ {
+ UUID id = getId();
+ Object idAttributeValue = attributes.get(ID);
+ if (idAttributeValue != null && !idAttributeValue.equals(id.toString()))
+ {
+ throw new IllegalConfigurationException("Cannot change existing configured object id");
+ }
+ }
+ }
+
protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
{
// allowed by default
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java
index 75b80eb56c..a6fe191523 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.model.AccessControlProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -43,6 +44,8 @@ import org.apache.qpid.server.util.MapValueConverter;
public class AccessControlProviderAdapter extends AbstractAdapter implements AccessControlProvider
{
+ private static final Logger LOGGER = Logger.getLogger(AccessControlProviderAdapter.class);
+
protected AccessControl _accessControl;
protected final Broker _broker;
@@ -217,8 +220,23 @@ public class AccessControlProviderAdapter extends AbstractAdapter implements Acc
{
if ((state == State.INITIALISING || state == State.QUIESCED) && _state.compareAndSet(state, State.ACTIVE))
{
- _accessControl.open();
- return true;
+ try
+ {
+ _accessControl.open();
+ return true;
+ }
+ catch(RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ if (_broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate ACL provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
}
else
{
@@ -235,7 +253,6 @@ public class AccessControlProviderAdapter extends AbstractAdapter implements Acc
return false;
}
-
return false;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
index 24f4757a18..5c4c8a53cd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
import javax.security.auth.login.AccountNotFoundException;
@@ -58,6 +59,7 @@ import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.util.MapValueConverter;
public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider
{
@@ -68,6 +70,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
protected Collection<String> _supportedAttributes;
protected Map<String, AuthenticationManagerFactory> _factories;
+ private AtomicReference<State> _state;
private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes, Collection<String> attributeNames)
{
@@ -76,6 +79,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
_broker = broker;
_supportedAttributes = createSupportedAttributes(attributeNames);
_factories = getAuthenticationManagerFactories();
+
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
addParent(Broker.class, broker);
// set attributes now after all attribute names are known
@@ -117,7 +123,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
@Override
public State getActualState()
{
- return null;
+ return _state.get();
}
@Override
@@ -191,7 +197,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
}
else if(STATE.equals(name))
{
- return State.ACTIVE; // TODO
+ return getActualState();
}
else if(TIME_TO_LIVE.equals(name))
{
@@ -214,6 +220,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
public boolean setState(State currentState, State desiredState)
throws IllegalStateTransitionException, AccessControlException
{
+ State state = _state.get();
if(desiredState == State.DELETED)
{
String providerName = getName();
@@ -227,20 +234,66 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
throw new IntegrityViolationException("Authentication provider '" + providerName + "' is set on port " + port.getName());
}
}
- _authManager.close();
- _authManager.onDelete();
- return true;
+
+ if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
+ && _state.compareAndSet(state, State.DELETED))
+ {
+ _authManager.close();
+ _authManager.onDelete();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot delete authentication provider in state: " + state);
+ }
}
else if(desiredState == State.ACTIVE)
{
- _authManager.initialise();
- return true;
+ if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED) && _state.compareAndSet(state, State.ACTIVE))
+ {
+ try
+ {
+ _authManager.initialise();
+ return true;
+ }
+ catch(RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ if (_broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate authentication provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot activate authentication provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.QUIESCED)
+ {
+ if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
+ {
+ return true;
+ }
}
else if(desiredState == State.STOPPED)
{
- _authManager.close();
- return true;
+ if (_state.compareAndSet(state, State.STOPPED))
+ {
+ _authManager.close();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot stop authentication provider in state: " + state);
+ }
}
+
return false;
}
@@ -256,11 +309,11 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
Map<String, Object> effectiveAttributes = super.generateEffectiveAttributes(attributes);
AuthenticationManager manager = validateAttributes(effectiveAttributes);
manager.initialise();
- _authManager = (T)manager;
- String type = (String)effectiveAttributes.get(AuthenticationManagerFactory.ATTRIBUTE_TYPE);
- AuthenticationManagerFactory managerFactory = _factories.get(type);
- _supportedAttributes = createSupportedAttributes(managerFactory.getAttributeNames());
super.changeAttributes(attributes);
+ _authManager = (T)manager;
+
+ // if provider was previously in ERRORED state then set its state to ACTIVE
+ _state.compareAndSet(State.ERRORED, State.ACTIVE);
}
private Map<String, AuthenticationManagerFactory> getAuthenticationManagerFactories()
@@ -287,6 +340,8 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
protected AuthenticationManager validateAttributes(Map<String, Object> attributes)
{
+ super.validateChangeAttributes(attributes);
+
String newName = (String)attributes.get(NAME);
String currentName = getName();
if (!currentName.equals(newName))
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
index a0e5bdb0e8..3bf62dc96b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
@@ -28,7 +28,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Group;
@@ -43,13 +45,17 @@ import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.group.GroupManager;
import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.util.MapValueConverter;
public class GroupProviderAdapter extends AbstractAdapter implements
GroupProvider
{
+ private static Logger LOGGER = Logger.getLogger(GroupProviderAdapter.class);
+
private final GroupManager _groupManager;
private final Broker _broker;
private Collection<String> _supportedAttributes;
+ private AtomicReference<State> _state;
public GroupProviderAdapter(UUID id, Broker broker, GroupManager groupManager, Map<String, Object> attributes, Collection<String> attributeNames)
{
@@ -62,6 +68,8 @@ public class GroupProviderAdapter extends AbstractAdapter implements
_groupManager = groupManager;
_broker = broker;
_supportedAttributes = createSupportedAttributes(attributeNames);
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
addParent(Broker.class, broker);
// set attributes now after all attribute names are known
@@ -104,7 +112,7 @@ public class GroupProviderAdapter extends AbstractAdapter implements
@Override
public State getActualState()
{
- return null;
+ return _state.get();
}
@Override
@@ -180,7 +188,7 @@ public class GroupProviderAdapter extends AbstractAdapter implements
}
else if (STATE.equals(name))
{
- return State.ACTIVE; // TODO
+ return getActualState();
}
else if (TIME_TO_LIVE.equals(name))
{
@@ -252,21 +260,67 @@ public class GroupProviderAdapter extends AbstractAdapter implements
@Override
protected boolean setState(State currentState, State desiredState)
{
+ State state = _state.get();
if (desiredState == State.ACTIVE)
{
- _groupManager.open();
- return true;
+ if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED)
+ && _state.compareAndSet(state, State.ACTIVE))
+ {
+ try
+ {
+ _groupManager.open();
+ return true;
+ }
+ catch(RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ if (_broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate group provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot activate group provider in state: " + state);
+ }
}
else if (desiredState == State.STOPPED)
{
- _groupManager.close();
- return true;
+ if (_state.compareAndSet(state, State.STOPPED))
+ {
+ _groupManager.close();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot stop group provider in state: " + state);
+ }
}
else if (desiredState == State.DELETED)
{
- _groupManager.close();
- _groupManager.onDelete();
- return true;
+ if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
+ && _state.compareAndSet(state, State.DELETED))
+ {
+ _groupManager.close();
+ _groupManager.onDelete();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot delete group provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.QUIESCED)
+ {
+ if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
+ {
+ return true;
+ }
}
return false;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
index 388427678e..de6ae06b94 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
@@ -309,7 +309,7 @@ public class PortAdapter extends AbstractAdapter implements Port
State state = _state.get();
if (desiredState == State.DELETED)
{
- if (state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED)
+ if (state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
{
return _state.compareAndSet(state, State.DELETED);
}
@@ -328,7 +328,7 @@ public class PortAdapter extends AbstractAdapter implements Port
}
catch(RuntimeException e)
{
- _state.compareAndSet(State.ACTIVE, state);
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
throw e;
}
return true;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java
new file mode 100644
index 0000000000..40f98b3b09
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java
@@ -0,0 +1,245 @@
+package org.apache.qpid.server.model;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory;
+import org.apache.qpid.server.security.group.FileGroupManagerFactory;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class ConfiguredObjectStateTransitionTest extends QpidTestCase
+{
+ private Broker _broker;
+ private RecovererProvider _recovererProvider;
+ private ConfigurationEntryStore _store;
+ private File _resourceToDelete;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+
+ _broker = BrokerTestHelper.createBrokerMock();
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ TaskExecutor executor = mock(TaskExecutor.class);
+ when(executor.isTaskExecutorThread()).thenReturn(true);
+ when(_broker.getTaskExecutor()).thenReturn(executor);
+
+ _recovererProvider = new DefaultRecovererProvider(statisticsGatherer, _broker.getVirtualHostRegistry(),
+ _broker.getLogRecorder(), _broker.getRootMessageLogger(), executor, new BrokerOptions());
+
+ _store = mock(ConfigurationEntryStore.class);
+
+ _resourceToDelete = new File(TMP_FOLDER, getTestName());
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ BrokerTestHelper.tearDown();
+ if (_resourceToDelete.exists())
+ {
+ _resourceToDelete.delete();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testGroupProviderValidStateTransitions() throws Exception
+ {
+ ConfigurationEntry providerEntry = getGroupProviderConfigurationEntry();
+ ConfiguredObject provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.QUIESCED);
+ assertValidStateTransition(provider, State.QUIESCED, State.STOPPED);
+
+ provider = createConfiguredObject(providerEntry);
+ assertValidStateTransition(provider, State.INITIALISING, State.DELETED);
+
+ providerEntry = getGroupProviderConfigurationEntry();
+ provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.QUIESCED);
+ assertValidStateTransition(provider, State.QUIESCED, State.DELETED);
+
+ providerEntry = getGroupProviderConfigurationEntry();
+ provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.ACTIVE);
+ assertValidStateTransition(provider, State.ACTIVE, State.DELETED);
+ }
+
+ public void testGroupProviderInvalidStateTransitions() throws Exception
+ {
+ ConfigurationEntry providerEntry = getGroupProviderConfigurationEntry();
+ assertAllInvalidStateTransitions(providerEntry);
+ }
+
+ public void testAuthenticationProviderValidStateTransitions()
+ {
+ ConfigurationEntry providerEntry = getAuthenticationProviderConfigurationEntry();
+ assertAllValidStateTransitions(providerEntry);
+ }
+
+ public void testAuthenticationProviderInvalidStateTransitions()
+ {
+ ConfigurationEntry providerEntry = getAuthenticationProviderConfigurationEntry();
+ assertAllInvalidStateTransitions(providerEntry);
+ }
+
+ public void testPortValidStateTransitions()
+ {
+ ConfigurationEntry providerEntry = getPortConfigurationEntry();
+ assertAllValidStateTransitions(providerEntry);
+ }
+
+ public void testPortInvalidStateTransitions()
+ {
+ ConfigurationEntry providerEntry = getPortConfigurationEntry();
+ assertAllInvalidStateTransitions(providerEntry);
+ }
+
+ private void assertAllInvalidStateTransitions(ConfigurationEntry providerEntry)
+ {
+ ConfiguredObject provider = createConfiguredObject(providerEntry);
+ assertInvalidStateTransition(provider, State.INITIALISING, State.REPLICA);
+
+ provider.setDesiredState(State.INITIALISING, State.QUIESCED);
+ assertInvalidStateTransition(provider, State.QUIESCED, State.INITIALISING);
+
+ provider.setDesiredState(State.QUIESCED, State.ACTIVE);
+ assertInvalidStateTransition(provider, State.ACTIVE, State.INITIALISING);
+
+ provider.setDesiredState(State.ACTIVE, State.DELETED);
+ assertInvalidStateTransition(provider, State.DELETED, State.INITIALISING);
+ assertInvalidStateTransition(provider, State.DELETED, State.QUIESCED);
+ assertInvalidStateTransition(provider, State.DELETED, State.ACTIVE);
+ assertInvalidStateTransition(provider, State.DELETED, State.REPLICA);
+ assertInvalidStateTransition(provider, State.DELETED, State.ERRORED);
+ }
+
+ private void assertAllValidStateTransitions(ConfigurationEntry providerEntry)
+ {
+ ConfiguredObject provider = createConfiguredObject(providerEntry);
+ assertNormalStateTransition(provider);
+
+ provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.QUIESCED);
+ assertValidStateTransition(provider, State.QUIESCED, State.STOPPED);
+
+ provider = createConfiguredObject(providerEntry);
+ assertValidStateTransition(provider, State.INITIALISING, State.DELETED);
+
+ provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.QUIESCED);
+ assertValidStateTransition(provider, State.QUIESCED, State.DELETED);
+
+ provider = createConfiguredObject(providerEntry);
+ provider.setDesiredState(State.INITIALISING, State.ACTIVE);
+ assertValidStateTransition(provider, State.ACTIVE, State.DELETED);
+ }
+
+ private void assertInvalidStateTransition(ConfiguredObject object, State initialState, State... invalidStates)
+ {
+ assertEquals("Unepxceted state", initialState, object.getActualState());
+ for (State state : invalidStates)
+ {
+ try
+ {
+ object.setDesiredState(initialState, state);
+ }
+ catch (IllegalStateException e)
+ {
+ // expected
+ }
+ assertEquals("Transition from state " + initialState + " into state " + state + " did occur", initialState,
+ object.getActualState());
+ }
+ }
+
+ private void assertValidStateTransition(ConfiguredObject object, State initialState, State... validStateSequence)
+ {
+ assertEquals("Unexpected state", initialState, object.getActualState());
+ State currentState = initialState;
+ for (State state : validStateSequence)
+ {
+ object.setDesiredState(currentState, state);
+ assertEquals("Transition from state " + currentState + " into state " + state + " did not occur", state,
+ object.getActualState());
+ currentState = state;
+ }
+ }
+
+ private void assertNormalStateTransition(ConfiguredObject object)
+ {
+ assertValidStateTransition(object, State.INITIALISING, State.QUIESCED, State.ACTIVE, State.STOPPED, State.DELETED);
+ }
+
+ private ConfiguredObject createConfiguredObject(ConfigurationEntry entry)
+ {
+ @SuppressWarnings("unchecked")
+ ConfiguredObjectRecoverer<ConfiguredObject> recoverer =
+ (ConfiguredObjectRecoverer<ConfiguredObject>)_recovererProvider.getRecoverer(entry.getType());
+ return recoverer.create(_recovererProvider, entry, _broker);
+ }
+
+ private ConfigurationEntry createConfigurationEntry(String type, Map<String, Object> attributes, ConfigurationEntryStore store)
+ {
+ return new ConfigurationEntry(UUID.randomUUID(), type, attributes, Collections.<UUID>emptySet(), store);
+ }
+
+ private ConfigurationEntry getAuthenticationProviderConfigurationEntry()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationProvider.NAME, getTestName());
+ attributes.put(AuthenticationProvider.TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE);
+ return createConfigurationEntry(AuthenticationProvider.class.getSimpleName(), attributes , _store);
+ }
+
+ private ConfigurationEntry getGroupProviderConfigurationEntry() throws Exception
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(GroupProvider.NAME, getTestName());
+ attributes.put(GroupProvider.TYPE, FileGroupManagerFactory.GROUP_FILE_PROVIDER_TYPE);
+ attributes.put(FileGroupManagerFactory.PATH, _resourceToDelete.getAbsolutePath());
+ if (!_resourceToDelete.exists())
+ {
+ _resourceToDelete.createNewFile();
+ }
+ return createConfigurationEntry(GroupProvider.class.getSimpleName(), attributes , _store);
+ }
+
+ private ConfigurationEntry getPortConfigurationEntry()
+ {
+ ConfigurationEntry authProviderEntry = getAuthenticationProviderConfigurationEntry();
+ AuthenticationProvider authProvider = (AuthenticationProvider)createConfiguredObject(authProviderEntry);
+
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, getTestName());
+ attributes.put(Port.PROTOCOLS, Collections.<Protocol>singleton(Protocol.HTTP));
+ attributes.put(Port.AUTHENTICATION_PROVIDER, authProvider.getName());
+ attributes.put(Port.PORT, 0);
+
+ when(_broker.findAuthenticationProviderByName(authProvider.getName())).thenReturn(authProvider);
+ return createConfigurationEntry(Port.class.getSimpleName(), attributes , _store);
+ }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java
index 861b246d54..312443cfa7 100644
--- a/java/systests/src/main/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java
@@ -25,10 +25,13 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.management.plugin.HttpManagement;
import org.apache.qpid.server.model.AccessControlProvider;
+import org.apache.qpid.server.model.State;
import org.apache.qpid.server.security.access.FileAccessControlProviderConstants;
import org.apache.qpid.test.utils.TestBrokerConfiguration;
import org.apache.qpid.test.utils.TestFileUtils;
@@ -230,6 +233,34 @@ public class AccessControlProviderRestTest extends QpidRestTestCase
assertCanAccessManagementInterface(accessControlProviderName2, true);
}
+ public void testRemovalOfAccessControlProviderInErrorStateUsingManagementMode() throws Exception
+ {
+ stopBroker();
+
+ File file = new File(TMP_FOLDER, getTestName());
+ if (file.exists())
+ {
+ file.delete();
+ }
+ assertFalse("ACL file should not exist", file.exists());
+ UUID id = getBrokerConfiguration().addAclFileConfiguration(file.getAbsolutePath());
+ getBrokerConfiguration().setSaved(false);
+ startBroker(0, true);
+
+ getRestTestHelper().setUsernameAndPassword(BrokerOptions.MANAGEMENT_MODE_USER_NAME, MANAGEMENT_MODE_PASSWORD);
+
+ Map<String, Object> acl = getRestTestHelper().getJsonAsSingletonList("/rest/accesscontrolprovider/" + TestBrokerConfiguration.ENTRY_NAME_ACL_FILE);
+ assertEquals("Unexpected id", id.toString(), acl.get(AccessControlProvider.ID));
+ assertEquals("Unexpected path", file.getAbsolutePath() , acl.get(FileAccessControlProviderConstants.PATH));
+ assertEquals("Unexpected state", State.ERRORED.name() , acl.get(AccessControlProvider.STATE));
+
+ int status = getRestTestHelper().submitRequest("/rest/accesscontrolprovider/" + TestBrokerConfiguration.ENTRY_NAME_ACL_FILE, "DELETE", null);
+ assertEquals("ACL was not deleted", 200, status);
+
+ List<Map<String, Object>> acls = getRestTestHelper().getJsonAsList("/rest/accesscontrolprovider/" + TestBrokerConfiguration.ENTRY_NAME_ACL_FILE);
+ assertEquals("ACL exists", 0, acls.size());
+ }
+
private void assertCanAccessManagementInterface(String accessControlProviderName, boolean canAccess) throws Exception
{
int expected = canAccess ? 200 : 403;
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
index 4ff0db8bc3..bb01d1facf 100644
--- a/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Port;
@@ -156,6 +157,103 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertEquals("Unexpected number of providers", 0, providerDetails.size());
}
+ public void testRemovalOfAuthenticationProviderInErrorStateUsingManagementMode() throws Exception
+ {
+ stopBroker();
+
+ File file = new File(TMP_FOLDER, getTestName());
+ if (file.exists())
+ {
+ file.delete();
+ }
+ assertFalse("Group file should not exist", file.exists());
+
+ TestBrokerConfiguration config = getBrokerConfiguration();
+
+ String providerName = getTestName();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ attributes.put(AuthenticationProvider.NAME, providerName);
+ attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, file.getAbsoluteFile());
+
+ UUID id = config.addAuthenticationProviderConfiguration(attributes);
+ config.setSaved(false);
+ startBroker(0, true);
+
+ getRestTestHelper().setUsernameAndPassword(BrokerOptions.MANAGEMENT_MODE_USER_NAME, MANAGEMENT_MODE_PASSWORD);
+
+ Map<String, Object> provider = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/" + providerName);
+ assertEquals("Unexpected id", id.toString(), provider.get(AuthenticationProvider.ID));
+ assertEquals("Unexpected name", providerName, provider.get(AuthenticationProvider.NAME));
+ assertEquals("Unexpected path", file.getAbsolutePath() , provider.get(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH));
+ assertEquals("Unexpected state", State.ERRORED.name() , provider.get(AuthenticationProvider.STATE));
+
+ int status = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "DELETE", null);
+ assertEquals("ACL was not deleted", 200, status);
+
+ List<Map<String, Object>> providers = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
+ assertEquals("Provider exists", 0, providers.size());
+ }
+
+ public void testUpdateOfAuthenticationProviderInErrorStateUsingManagementMode() throws Exception
+ {
+ stopBroker();
+
+ File file = new File(TMP_FOLDER, getTestName());
+ if (file.exists())
+ {
+ file.delete();
+ }
+ assertFalse("Group file should not exist", file.exists());
+
+ TestBrokerConfiguration config = getBrokerConfiguration();
+
+ String providerName = getTestName();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ attributes.put(AuthenticationProvider.NAME, providerName);
+ attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, file.getAbsoluteFile());
+
+ UUID id = config.addAuthenticationProviderConfiguration(attributes);
+ config.setSaved(false);
+ startBroker(0, true);
+
+ getRestTestHelper().setUsernameAndPassword(BrokerOptions.MANAGEMENT_MODE_USER_NAME, MANAGEMENT_MODE_PASSWORD);
+
+ Map<String, Object> provider = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/" + providerName);
+ assertEquals("Unexpected id", id.toString(), provider.get(AuthenticationProvider.ID));
+ assertEquals("Unexpected name", providerName, provider.get(AuthenticationProvider.NAME));
+ assertEquals("Unexpected path", file.getAbsolutePath() , provider.get(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH));
+ assertEquals("Unexpected state", State.ERRORED.name() , provider.get(AuthenticationProvider.STATE));
+
+ File principalDatabase = null;
+ try
+ {
+ principalDatabase = getRestTestHelper().createTemporaryPasswdFile(new String[]{"admin2", "guest2", "test2"});
+ attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationProvider.NAME, providerName);
+ attributes.put(AuthenticationProvider.ID, id);
+ attributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, principalDatabase.getAbsolutePath());
+
+ int status = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
+ assertEquals("ACL was not deleted", 200, status);
+
+ provider = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/" + providerName);
+ assertEquals("Unexpected id", id.toString(), provider.get(AuthenticationProvider.ID));
+ assertEquals("Unexpected name", providerName, provider.get(AuthenticationProvider.NAME));
+ assertEquals("Unexpected path", principalDatabase.getAbsolutePath() , provider.get(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH));
+ assertEquals("Unexpected state", State.ACTIVE.name() , provider.get(AuthenticationProvider.STATE));
+ }
+ finally
+ {
+ if (principalDatabase != null)
+ {
+ principalDatabase.delete();
+ }
+ }
+ }
+
public void testCreateAndDeletePasswordAuthenticationProviderWithNonExistingFile() throws Exception
{
stopBroker();
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
index ef8e12a929..d09d5a8d02 100644
--- a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
@@ -26,7 +26,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.UUID;
+import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.model.Group;
import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.LifetimePolicy;
@@ -285,6 +287,37 @@ public class GroupProviderRestTest extends QpidRestTestCase
}
}
+ public void testRemovalOfGroupProviderInErrorStateUsingManagementMode() throws Exception
+ {
+ stopBroker();
+
+ File file = new File(TMP_FOLDER, getTestName());
+ if (file.exists())
+ {
+ file.delete();
+ }
+ assertFalse("Group file should not exist", file.exists());
+
+ TestBrokerConfiguration config = getBrokerConfiguration();
+ config.removeObjectConfiguration(TestBrokerConfiguration.ENTRY_NAME_GROUP_FILE);
+ UUID id = config.addGroupFileConfiguration(file.getAbsolutePath());
+ config.setSaved(false);
+ startBroker(0, true);
+
+ getRestTestHelper().setUsernameAndPassword(BrokerOptions.MANAGEMENT_MODE_USER_NAME, MANAGEMENT_MODE_PASSWORD);
+
+ Map<String, Object> groupProvider = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + TestBrokerConfiguration.ENTRY_NAME_GROUP_FILE);
+ assertEquals("Unexpected id", id.toString(), groupProvider.get(GroupProvider.ID));
+ assertEquals("Unexpected path", file.getAbsolutePath() , groupProvider.get(FileGroupManagerFactory.PATH));
+ assertEquals("Unexpected state", State.ERRORED.name() , groupProvider.get(GroupProvider.STATE));
+
+ int status = getRestTestHelper().submitRequest("/rest/groupprovider/" + TestBrokerConfiguration.ENTRY_NAME_GROUP_FILE, "DELETE", null);
+ assertEquals("ACL was not deleted", 200, status);
+
+ List<Map<String, Object>> providers = getRestTestHelper().getJsonAsList("/rest/groupprovider/" + TestBrokerConfiguration.ENTRY_NAME_GROUP_FILE);
+ assertEquals("Provider exists", 0, providers.size());
+ }
+
private void assertProvider(String name, String type, Map<String, Object> provider)
{
Asserts.assertAttributesPresent(provider, GroupProvider.AVAILABLE_ATTRIBUTES,