Skip to content

Commit a2d2382

Browse files
baranowbbstansberry
authored andcommitted
AS7.1-5929
1 parent 059bed5 commit a2d2382

File tree

4 files changed

+190
-37
lines changed

4 files changed

+190
-37
lines changed

controller/src/main/java/org/jboss/as/controller/ControlledProcessState.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,9 @@
2222

2323
package org.jboss.as.controller;
2424

25-
import java.beans.PropertyChangeSupport;
2625
import java.util.concurrent.atomic.AtomicInteger;
2726
import java.util.concurrent.atomic.AtomicStampedReference;
2827

29-
import org.jboss.msc.service.ServiceController;
30-
import org.jboss.msc.service.ServiceName;
31-
3228
/**
3329
* The overall state of a process that is being managed by a {@link ModelController}.
3430
*
@@ -80,6 +76,8 @@ public String toString() {
8076
private final boolean reloadSupported;
8177
private final ControlledProcessStateService service;
8278

79+
private boolean restartRequiredFlag = false;
80+
8381
public ControlledProcessState(final boolean reloadSupported) {
8482
this.reloadSupported = reloadSupported;
8583
service = new ControlledProcessStateService(State.STARTING);
@@ -103,8 +101,13 @@ public void setStarting() {
103101

104102
public void setRunning() {
105103
synchronized (service) {
106-
state.set(State.RUNNING, stamp.incrementAndGet());
107-
service.stateChanged(State.RUNNING);
104+
if(restartRequiredFlag){
105+
state.set(State.RESTART_REQUIRED, stamp.incrementAndGet());
106+
service.stateChanged(State.RESTART_REQUIRED);
107+
}else{
108+
state.set(State.RUNNING, stamp.incrementAndGet());
109+
service.stateChanged(State.RUNNING);
110+
}
108111
}
109112
}
110113

@@ -119,7 +122,6 @@ public Object setReloadRequired() {
119122
if (!reloadSupported) {
120123
return setRestartRequired();
121124
}
122-
123125
AtomicStampedReference<State> stateRef = state;
124126
int newStamp = stamp.incrementAndGet();
125127
int[] receiver = new int[1];
@@ -151,6 +153,7 @@ public Object setRestartRequired() {
151153
}
152154
synchronized (service) {
153155
if (stateRef.compareAndSet(was, State.RESTART_REQUIRED, receiver[0], newStamp)) {
156+
restartRequiredFlag = true;
154157
service.stateChanged(State.RESTART_REQUIRED);
155158
break;
156159
}
@@ -178,6 +181,7 @@ public void revertRestartRequired(Object stamp) {
178181
Integer theirStamp = Integer.class.cast(stamp);
179182
synchronized (service) {
180183
if (state.compareAndSet(State.RESTART_REQUIRED, State.RUNNING, theirStamp, this.stamp.incrementAndGet())) {
184+
restartRequiredFlag = false;
181185
service.stateChanged(State.RUNNING);
182186
}
183187
}

testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/management/cli/GlobalOpsTestCase.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
*/
2222
package org.jboss.as.test.integration.management.cli;
2323

24-
import org.jboss.as.test.integration.management.base.AbstractCliTestBase;
24+
import static org.junit.Assert.assertEquals;
25+
import static org.junit.Assert.assertNotNull;
26+
import static org.junit.Assert.assertNull;
2527
import static org.junit.Assert.assertTrue;
2628

2729
import java.net.URL;
@@ -33,7 +35,9 @@
3335
import org.jboss.arquillian.container.test.api.RunAsClient;
3436
import org.jboss.arquillian.junit.Arquillian;
3537
import org.jboss.arquillian.test.api.ArquillianResource;
38+
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
3639
import org.jboss.as.test.integration.common.HttpRequest;
40+
import org.jboss.as.test.integration.management.base.AbstractCliTestBase;
3741
import org.jboss.as.test.integration.management.util.CLIOpResult;
3842
import org.jboss.shrinkwrap.api.Archive;
3943
import org.jboss.shrinkwrap.api.ShrinkWrap;
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* JBoss, Home of Professional Open Source.
3+
* Copyright 2011, Red Hat, Inc., and individual contributors
4+
* as indicated by the @author tags. See the copyright.txt file in the
5+
* distribution for a full listing of individual contributors.
6+
*
7+
* This is free software; you can redistribute it and/or modify it
8+
* under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation; either version 2.1 of
10+
* the License, or (at your option) any later version.
11+
*
12+
* This software is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this software; if not, write to the Free
19+
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20+
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21+
*/
22+
23+
package org.jboss.as.test.manualmode.management.cli;
24+
25+
import static org.junit.Assert.assertEquals;
26+
import static org.junit.Assert.assertNotNull;
27+
import static org.junit.Assert.assertNull;
28+
import static org.junit.Assert.assertTrue;
29+
30+
import java.util.Map;
31+
import java.util.concurrent.TimeUnit;
32+
33+
import org.jboss.arquillian.container.test.api.ContainerController;
34+
import org.jboss.arquillian.container.test.api.Deployer;
35+
import org.jboss.arquillian.container.test.api.Deployment;
36+
import org.jboss.arquillian.container.test.api.RunAsClient;
37+
import org.jboss.arquillian.container.test.api.TargetsContainer;
38+
import org.jboss.arquillian.junit.Arquillian;
39+
import org.jboss.arquillian.test.api.ArquillianResource;
40+
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
41+
import org.jboss.as.test.integration.management.base.AbstractCliTestBase;
42+
import org.jboss.as.test.integration.management.util.CLIOpResult;
43+
import org.jboss.shrinkwrap.api.Archive;
44+
import org.jboss.shrinkwrap.api.ShrinkWrap;
45+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
46+
import org.junit.After;
47+
import org.junit.Before;
48+
import org.junit.Test;
49+
import org.junit.runner.RunWith;
50+
51+
/**
52+
*
53+
* @author baranowb
54+
*/
55+
@RunWith(Arquillian.class)
56+
@RunAsClient
57+
public class GlobalOpsTestCase extends AbstractCliTestBase {
58+
59+
public static final String DEFAULT_JBOSSAS = "default-jbossas";
60+
public static final String DEPLOYMENT_NAME = "DUMMY";
61+
62+
@ArquillianResource
63+
private static ContainerController container;
64+
@ArquillianResource
65+
private Deployer deployer;
66+
67+
//NOTE: BeforeClass is not subject to ARQ injection.
68+
@Before
69+
public void initServer() throws Exception {
70+
container.start(DEFAULT_JBOSSAS);
71+
initCLI();
72+
}
73+
74+
@After
75+
public void closeServer() throws Exception {
76+
closeCLI();
77+
container.stop(DEFAULT_JBOSSAS);
78+
}
79+
80+
@Deployment(name = DEPLOYMENT_NAME, managed = false)
81+
@TargetsContainer(DEFAULT_JBOSSAS)
82+
public static Archive<?> getDeployment() {
83+
JavaArchive ja = ShrinkWrap.create(JavaArchive.class, "dummy.jar");
84+
ja.addClass(GlobalOpsTestCase.class);
85+
return ja;
86+
}
87+
88+
89+
@Test
90+
public void testPersistentRestart() throws Exception {
91+
//AS7-5929
92+
cli.sendLine(":server-set-restart-required");
93+
CLIOpResult result = cli.readAllAsOpResult();
94+
assertTrue(result.isIsOutcomeSuccess());
95+
checkResponseHeadersForProcessState(result);
96+
cli.sendLine(":read-resource");
97+
result = cli.readAllAsOpResult();
98+
assertTrue(result.isIsOutcomeSuccess());
99+
checkResponseHeadersForProcessState(result);
100+
101+
102+
boolean sendLineResult = cli.sendLine(":reload",true);
103+
assertTrue(sendLineResult);
104+
//null when comm is broken on :reload before answer is sent.
105+
if (cli.readOutput() != null) {
106+
result = cli.readAllAsOpResult();
107+
assertTrue(result.isIsOutcomeSuccess());
108+
assertNoProcessState(result);
109+
}
110+
111+
while(!cli.sendConnect()){
112+
TimeUnit.SECONDS.sleep(2);
113+
}
114+
115+
cli.sendLine(":read-resource");
116+
result = cli.readAllAsOpResult();
117+
assertTrue(result.isIsOutcomeSuccess());
118+
checkResponseHeadersForProcessState(result);
119+
120+
}
121+
122+
protected void checkResponseHeadersForProcessState(CLIOpResult result) {
123+
assertNotNull("No response headers!", result.getFromResponse(ModelDescriptionConstants.RESPONSE_HEADERS));
124+
Map responseHeaders = (Map) result.getFromResponse(ModelDescriptionConstants.RESPONSE_HEADERS);
125+
Object processState = responseHeaders.get("process-state");
126+
assertNotNull("No process state in response-headers!", processState);
127+
assertTrue("Process state is of wrong type!", processState instanceof String);
128+
assertEquals("Wrong content of process-state header", "restart-required", (String) processState);
129+
130+
}
131+
132+
protected void assertNoProcessState(CLIOpResult result) {
133+
if(result.getFromResponse(ModelDescriptionConstants.RESPONSE_HEADERS) == null){
134+
return;
135+
}
136+
Map responseHeaders = (Map) result.getFromResponse(ModelDescriptionConstants.RESPONSE_HEADERS);
137+
Object processState = responseHeaders.get("process-state");
138+
assertNull(processState);
139+
140+
141+
}
142+
}

testsuite/shared/src/main/java/org/jboss/as/test/integration/management/util/CLIOpResult.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,35 @@
2828
import java.util.Map;
2929
import java.util.Set;
3030

31+
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
3132
import org.jboss.dmr.ModelNode;
3233
import org.jboss.dmr.ModelType;
3334
import org.jboss.dmr.Property;
3435

35-
3636
/**
37-
*
37+
*
3838
* @author Dominik Pospisil <dpospisi@redhat.com>
39+
* @author baranowb
3940
*/
4041
public class CLIOpResult {
4142

4243
private boolean isOutcomeSuccess;
43-
private Object result;
44-
private Object serverGroups;
44+
private Map<String, Object> responseMap;
4545

46-
public CLIOpResult() {}
46+
public CLIOpResult() {
47+
this.responseMap = new HashMap<String, Object>();
48+
}
4749

4850
public CLIOpResult(ModelNode node) {
49-
final Map<String, Object> map = toMap(node);
50-
isOutcomeSuccess = "success".equals(map.get("outcome"));
51-
result = map.get("result");
52-
serverGroups = map.get("server-groups");
51+
this.responseMap = toMap(node);
52+
this.isOutcomeSuccess = ModelDescriptionConstants.SUCCESS.equals(this.responseMap
53+
.get(ModelDescriptionConstants.OUTCOME));
5354
}
5455

5556
protected Map<String, Object> toMap(ModelNode node) {
5657
final Set<String> keys = node.keys();
57-
Map<String,Object> map = new HashMap<String,Object>(keys.size());
58-
for(String key : keys) {
58+
Map<String, Object> map = new HashMap<String, Object>(keys.size());
59+
for (String key : keys) {
5960
map.put(key, toObject(node.get(key)));
6061
}
6162
return map;
@@ -64,19 +65,19 @@ protected Map<String, Object> toMap(ModelNode node) {
6465
protected List<Object> toList(ModelNode node) {
6566
final List<ModelNode> nodeList = node.asList();
6667
final List<Object> list = new ArrayList<Object>(nodeList.size());
67-
for(ModelNode item : nodeList) {
68+
for (ModelNode item : nodeList) {
6869
list.add(toObject(item));
6970
}
7071
return list;
7172
}
7273

7374
protected Object toObject(ModelNode node) {
7475
final ModelType type = node.getType();
75-
if(type.equals(ModelType.LIST)) {
76+
if (type.equals(ModelType.LIST)) {
7677
return toList(node);
77-
} else if(type.equals(ModelType.OBJECT)) {
78+
} else if (type.equals(ModelType.OBJECT)) {
7879
return toMap(node);
79-
} else if(type.equals(ModelType.PROPERTY)) {
80+
} else if (type.equals(ModelType.PROPERTY)) {
8081
final Property prop = node.asProperty();
8182
return Collections.singletonMap(prop.getName(), toObject(prop.getValue()));
8283
} else {
@@ -93,15 +94,29 @@ public void setIsOutcomeSuccess(boolean isOutcomeSuccess) {
9394
}
9495

9596
public Object getResult() {
96-
return result;
97+
return this.getFromResponse(ModelDescriptionConstants.RESULT);
98+
}
99+
100+
public Object getServerGroups() {
101+
return getFromResponse(ModelDescriptionConstants.SERVER_GROUPS);
102+
}
103+
104+
/**
105+
* Return top entry from response, ie -"response-headers", "outcome", ... etc
106+
*
107+
* @param key
108+
* @return
109+
*/
110+
public Object getFromResponse(String key) {
111+
return this.responseMap.get(key);
97112
}
98113

99114
/**
100115
* Get the result as map or null if the result is not a map
101116
*/
102117
@SuppressWarnings("unchecked")
103118
public Map<String, Object> getResultAsMap() {
104-
return (Map<String, Object>) (result instanceof Map ? result : null);
119+
return (Map<String, Object>) (responseMap instanceof Map ? responseMap : null);
105120
}
106121

107122
/**
@@ -120,16 +135,4 @@ public Map<String, Object> getNamedResultAsMap(String key) {
120135
Object value = getNamedResult(key);
121136
return (Map<String, Object>) (value instanceof Map ? value : null);
122137
}
123-
124-
public void setResult(Object result) {
125-
this.result = result;
126-
}
127-
128-
public Object getServerGroups() {
129-
return serverGroups;
130-
}
131-
132-
public void setServerGroups(Object serverGroups) {
133-
this.serverGroups = serverGroups;
134-
}
135138
}

0 commit comments

Comments
 (0)