Skip to content

Commit 2acee3e

Browse files
author
John E. Bailey
committed
[JBAS-8690] - Execute deployment updates as a service with the proper dependencies
1 parent 8ef5e52 commit 2acee3e

File tree

3 files changed

+108
-36
lines changed

3 files changed

+108
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* JBoss, Home of Professional Open Source.
3+
* Copyright 2010, 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.server;
24+
25+
import java.util.List;
26+
import org.jboss.as.deployment.ServerDeploymentRepository;
27+
import org.jboss.as.deployment.unit.DeploymentUnitProcessor;
28+
import org.jboss.as.model.AbstractServerModelUpdate;
29+
import org.jboss.as.model.BootUpdateContext;
30+
import org.jboss.msc.service.BatchBuilder;
31+
import org.jboss.msc.service.Service;
32+
import org.jboss.msc.service.ServiceContainer;
33+
import org.jboss.msc.service.ServiceName;
34+
import org.jboss.msc.service.ServiceRegistryException;
35+
import org.jboss.msc.service.StartContext;
36+
import org.jboss.msc.service.StartException;
37+
import org.jboss.msc.service.StopContext;
38+
39+
/**
40+
* Service used to execute deployment updates once required deployment dependencies are available.
41+
*
42+
* @author John Bailey
43+
*/
44+
public class DeploymentUpdateService implements Service<Void> {
45+
private static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("deployment", "updates");
46+
private final List<AbstractServerModelUpdate<?>> updates;
47+
private final ServerStartupListener serverStartupListener;
48+
49+
static final void addService(final BatchBuilder batchBuilder, final List<AbstractServerModelUpdate<?>> updates, final ServerStartupListener serverStartupListener) {
50+
batchBuilder.addService(SERVICE_NAME, new DeploymentUpdateService(updates, serverStartupListener))
51+
.addDependency(ServerDeploymentRepository.SERVICE_NAME);
52+
}
53+
54+
public DeploymentUpdateService(final List<AbstractServerModelUpdate<?>> updates, final ServerStartupListener serverStartupListener) {
55+
this.updates = updates;
56+
this.serverStartupListener = serverStartupListener;
57+
}
58+
59+
public void start(StartContext context) throws StartException {
60+
final ServiceContainer serviceContainer = context.getController().getServiceContainer();
61+
62+
final ServerStartBatchBuilder batchBuilder = new ServerStartBatchBuilder(serviceContainer.batchBuilder(), serverStartupListener);
63+
batchBuilder.addListener(serverStartupListener);
64+
65+
final BootUpdateContext updateContext = new BootUpdateContext() {
66+
public BatchBuilder getBatchBuilder() {
67+
return batchBuilder;
68+
}
69+
70+
public ServiceContainer getServiceContainer() {
71+
return serviceContainer;
72+
}
73+
74+
public void addDeploymentProcessor(DeploymentUnitProcessor processor, long priority) {
75+
throw new UnsupportedOperationException("Deployments are not allowed to add deployment unit processors");
76+
}
77+
};
78+
79+
// Deployment chain should be configured now..
80+
for (AbstractServerModelUpdate<?> update : updates) {
81+
if(update.isDeploymentUpdate()) {
82+
update.applyUpdateBootAction(updateContext);
83+
}
84+
}
85+
86+
try {
87+
batchBuilder.install();
88+
serverStartupListener.finish();
89+
} catch (ServiceRegistryException e) {
90+
throw new IllegalStateException("Failed to install deployment services", e);
91+
}
92+
}
93+
94+
public void stop(StopContext context) {
95+
}
96+
97+
public Void getValue() throws IllegalStateException {
98+
return null;
99+
}
100+
}

server/src/main/java/org/jboss/as/server/ServerStartTask.java

+2-10
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@
7474
/**
7575
* @author <a href="mailto:[email protected]">David M. Lloyd</a>
7676
*/
77-
public final class
78-
ServerStartTask implements ServerTask, Serializable, ObjectInputValidation {
77+
public final class ServerStartTask implements ServerTask, Serializable, ObjectInputValidation {
7978

8079
public static final ServiceName AS_SERVER_SERVICE_NAME = ServiceName.JBOSS.append("as", "server");
8180

@@ -234,19 +233,12 @@ public void addDeploymentProcessor(DeploymentUnitProcessor processor, long prior
234233
}
235234
}
236235

237-
// Deployment chain should be configured now..
238-
for (AbstractServerModelUpdate<?> update : updates) {
239-
if(update.isDeploymentUpdate()) {
240-
update.applyUpdateBootAction(context);
241-
}
242-
}
236+
DeploymentUpdateService.addService(batchBuilder, updates, serverStartupListener);
243237

244238
StandaloneServerManagementServices.addServices(serverModel, container, batchBuilder);
245239

246240
try {
247-
serverStartupListener.finish();
248241
batchBuilder.install();
249-
serverStartupListener.finishBatch();
250242
} catch (ServiceRegistryException e) {
251243
throw new IllegalStateException("Failed to install boot services", e);
252244
}

server/src/main/java/org/jboss/as/server/ServerStartupListener.java

+6-26
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ public class ServerStartupListener extends AbstractServiceListener<Object>{
5050
private final long start = Module.getStartTime();
5151
private final Map<ServiceName, StartException> serviceFailures = new HashMap<ServiceName, StartException>();
5252
private final Callback finishCallback;
53-
private Runnable batchCallback;
5453
private final Set<ServiceName> expectedNonActiveServices = new HashSet<ServiceName>();
55-
private final AtomicBoolean finished = new AtomicBoolean();
5654
private final AtomicBoolean callbackRan = new AtomicBoolean();
5755

5856
private static final AtomicIntegerFieldUpdater<ServerStartupListener> countUpdater = AtomicIntegerFieldUpdater.newUpdater(ServerStartupListener.class, "count");
@@ -84,7 +82,7 @@ public void serviceStarted(final ServiceController<? extends Object> serviceCont
8482
startedOnDemandServicesUpdater.incrementAndGet(this);
8583
}
8684
if (!expectedNonActiveServices.contains(serviceController.getName()) && countUpdater.decrementAndGet(this) == 0) {
87-
batchComplete();
85+
complete();
8886
}
8987
serviceController.removeListener(this);
9088
}
@@ -95,37 +93,19 @@ public void serviceFailed(ServiceController<? extends Object> serviceController,
9593
log.errorf(reason, "Service [%s] start failed", serviceName);
9694
serviceFailures.put(serviceName, reason);
9795
if (!expectedNonActiveServices.contains(serviceController.getName()) && countUpdater.decrementAndGet(this) == 0) {
98-
batchComplete();
96+
complete();
9997
}
10098
serviceController.removeListener(this);
10199
}
102100

103-
public void startBatch(final Runnable batchCallback) {
104-
if(finished.get()) {
105-
throw new IllegalStateException("Listener is already finished");
106-
}
107-
if(!countUpdater.compareAndSet(this, 0, 1)) {
108-
throw new IllegalStateException("Listener already has a started batch");
109-
}
110-
this.batchCallback = batchCallback;
111-
}
112-
113-
public void finishBatch() {
101+
public void finish() {
114102
if (countUpdater.decrementAndGet(this) == 0) {
115-
batchComplete();
103+
complete();
116104
}
117105
}
118106

119-
public void finish() {
120-
finished.set(true);
121-
}
122-
123-
private void batchComplete() {
124-
boolean finished = this.finished.get(); // Check first in case the batch callback invokes finish, which would not be valid for this batch
125-
if(batchCallback != null) {
126-
batchCallback.run();
127-
}
128-
if(finished && callbackRan.compareAndSet(false, true)) {
107+
private void complete() {
108+
if(callbackRan.compareAndSet(false, true)) {
129109
final long end = System.currentTimeMillis();
130110
finishCallback.run(serviceFailures, end - start, totalServices, expectedNonActiveServices.size() - startedOnDemandServicesUpdater.get(this), startedServices);
131111
}

0 commit comments

Comments
 (0)