1 package com.maxiq.tools.jboss;
2
3 import java.util.Date;
4 import java.text.SimpleDateFormat;
5
6 import java.io.File;
7 import java.io.IOException;
8
9 import java.net.URL;
10 import java.net.MalformedURLException;
11
12 /***
13 * Bean capable of monitoring the deployment status of a particular
14 * artifact into the JBoss environment. Upon a call to execute()
15 * a polled wait is performed until the specified condition is met or
16 * timeout occurs.
17 * <br>Note that the system property <code>com.maxiq.tools.jboss.home"</code>
18 * should be properly set to the home of a running JBoss installation.
19 *
20 * @author <a href="mailto:fvancea@maxiq.com">Florin Vancea</a>
21 */
22 public class JMXDeploymentMonitor extends JMXBean {
23
24 /*** How do we want the artifact's deployment status to be? */
25 private boolean wantedStatus = true;
26 /*** Storage space for the "url" attribute as String */
27 private String url = null;
28 /*** Storage space for the "file" attribute as String */
29 private String file = null;
30 /*** Timeout. Defaults to 10000 msec == 10 sec */
31 private long timeoutMsec = 10000;
32
33 /*** The actual URL, derived from either "url" or "file" */
34 private URL artifactURL = null;
35 /*** Time formatter, for logging/debugging */
36 private SimpleDateFormat formatter = new SimpleDateFormat("[HH:mm:ss,SSS]");
37
38 /***
39 * Set the URL of the artifact as a String.
40 * Optional, alternative for "file".
41 * @param url A String representing an URL in external form
42 * @throws MalformedURLException when the String-URL is not OK
43 */
44 public void setUrl(String url) throws MalformedURLException {
45 if (this.file != null) {
46 throw new RuntimeException("Either url or file is allowed");
47 }
48 this.url = url;
49 this.artifactURL = null; // next method may throw MalformedURLException
50 this.artifactURL = new URL(url);
51 }
52
53 /***
54 * Get the URL of the artifact as a String.
55 * @return the String representation of the work URL.
56 */
57 public String getUrl() {
58 if (artifactURL != null)
59 return artifactURL.toExternalForm();
60 else
61 return url;
62 }
63
64 /***
65 * Set the artifact as a file path. Optional, alternative for "url".
66 * If the path is relative, it is interpreted relative to the
67 * "standard" deploy dir under the running config.
68 *
69 * @param file String path
70 */
71 public void setFile(String file) {
72 if (this.url != null) {
73 throw new RuntimeException("Either url or file is allowed");
74 }
75 this.file = file;
76 // setting the artifactURL is deferred until execute. We need all the
77 // attributes if the path is relative, to query the serverdir.
78 /*
79 try {
80 this.artifactURL = (new File(file)).getCanonicalFile().toURL();
81 } catch (IOException ioex) {
82 this.artifactURL = null;
83 throw new RuntimeException("Cannot canonify file name");
84 }
85 */
86 }
87
88 /***
89 * Get the artifact as a file path. Works only if "file" was set.
90 * @return Filepath as string (if set previously through "file"
91 */
92 public String getFile() {
93 return file;
94 }
95
96 /***
97 * Set timeout (msec). Optional. Implicit 10000.
98 * @param msec Timeout in msec.
99 */
100 public void setTimeout(long msec) {
101 this.timeoutMsec = msec;
102 }
103
104 /***
105 * Get timeout (msec).
106 * @return Timeout in msec
107 */
108 public long getTimeout() {
109 return timeoutMsec;
110 }
111
112 /***
113 * Set wanted deployment status.
114 * @param wantedStatus <code>true</code>
115 * if we wait for the artifact to be deployed,
116 * <code>false</code> if we wait for the artifact to be undeployed.
117 */
118 public void setWantedStatus(boolean wantedStatus) {
119 this.wantedStatus = wantedStatus;
120 }
121
122 /***
123 * Get wanted deployment status.
124 * @return See above
125 */
126 public boolean getWantedStatus() {
127 return wantedStatus;
128 }
129
130 /***
131 * "execute" method allows using this as Ant task via Ant's proxy.
132 * It actually performs waitForStatus(wantedStatus).
133 * If timeout occurs, throws WaitTimeoutException (unchecked)
134 * @throws JBossNotAvailable when it seems there's no JBoss to talk with
135 */
136 public void execute() throws JBossNotAvailable {
137 prepareArtifactURL();
138 boolean result = false;
139 try {
140 result = waitForStatus(artifactURL, wantedStatus, timeoutMsec);
141 } catch(RuntimeException rtex) {
142 rtex.printStackTrace(System.out);
143 throw rtex;
144 }
145 if (!result) {
146 String msg = "Timeout waiting for "
147 + (wantedStatus ? "deployment" : "undeployment")
148 + " of " + artifactURL.toExternalForm();
149 System.out.println(msg);
150 throw new WaitTimeoutException(msg);
151 }
152 }
153
154 /***
155 * Checks the deployment status of the specified artifact.
156 * Used in "bean mode".
157 * @return The deployment status. <code>true</code> if currently deployed.
158 */
159 public boolean isDeployed() throws JBossNotAvailable {
160 prepareArtifactURL();
161 setMbean("jboss.system:service=MainDeployer");
162 setMethod("isDeployed");
163 clearArguments();
164 addArgument(artifactURL, "java.net.URL");
165 Object lrv = null;
166 doExecute();
167 lrv = getLastReturnValue();
168 if (lrv == null) {
169 throw new JBossNotAvailable(
170 "Bad return value from call to \"isDeployed\"");
171 }
172 return String.valueOf(true).equals(lrv.toString());
173 }
174
175 /***
176 * Convenience method for "bean mode".<br>
177 * Waits for the deployment status to be expectedStatus.
178 * @return <code>true</code> when successful
179 */
180 public boolean waitForDeploy(boolean expectedStatus)
181 throws JBossNotAvailable {
182 prepareArtifactURL();
183 boolean rv = waitForStatus(artifactURL, expectedStatus, timeoutMsec);
184 if (!rv) {
185 System.out.println(formatter.format(new Date())
186 + "WARNING: wait failed");
187 }
188 return rv;
189 }
190
191 /***
192 * Waits for the specified goal to be attained or for timeout to occur.
193 * @return <code>true</code> if the wait succeeded
194 * @param artifact URL of the artifact to be monitored
195 * @param wantedDepStatus The wanted deployment status
196 * @param timeout Timeout value (msec)
197 * @throws JBossNotAvailable when there's no JBoss to wait for
198 */
199 public boolean waitForStatus(
200 URL artifact, boolean wantedDepStatus, long timeout)
201 throws JBossNotAvailable {
202
203 setMbean("jboss.system:service=MainDeployer");
204 setMethod("isDeployed");
205 clearArguments();
206 addArgument(artifact, "java.net.URL");
207
208 long startTime = System.currentTimeMillis();
209 Object lrv = null;
210 String wantedString = String.valueOf(wantedDepStatus);
211 while (true) {
212 if (System.currentTimeMillis() - startTime > timeout) {
213 return false;
214 }
215 // don't eat up the processor...
216 // maybe a sleep() would be more appropriate,
217 // since the timing is not critical and it would save some JMX calls
218 Thread.currentThread().yield();
219 doExecute();
220 lrv = getLastReturnValue();
221 if (lrv == null) {
222 throw new JBossNotAvailable(
223 "Bad return value from call to \"isDeployed\"");
224 }
225 if (wantedString.equals(lrv.toString())) {
226 return true;
227 }
228 }
229 }
230
231 private void prepareArtifactURL() throws JBossNotAvailable {
232 if (artifactURL == null) {
233 if (file == null) {
234 throw new IllegalArgumentException(
235 "Either file or url attribute is required.");
236 }
237 File theFile = new File(file);
238 if (!theFile.isAbsolute()) {
239 File deployDir = new File(
240 (File) getJMXProxy().getAttribute(
241 "jboss.system:type=ServerConfig","ServerHomeDir"),
242 "deploy");
243 theFile = new File(deployDir, theFile.getPath());
244 }
245 try {
246 this.artifactURL = theFile.getCanonicalFile().toURL();
247 } catch (IOException ioex) {
248 this.artifactURL = null;
249 throw new RuntimeException("Cannot canonify file name");
250 }
251 }
252 }
253
254 }
This page was automatically generated by Maven