3232import java .util .List ;
3333import java .util .Map ;
3434import java .util .Set ;
35+ import java .util .regex .Matcher ;
3536
3637import org .codehaus .jackson .JsonNode ;
3738
5859import org .rhq .core .util .ByteUtil ;
5960import org .rhq .core .util .file .ContentFileInfo ;
6061import org .rhq .core .util .file .JarContentFileInfo ;
62+ import org .rhq .modules .plugins .jbossas7 .helper .Deployer ;
6163import org .rhq .modules .plugins .jbossas7 .json .Address ;
6264import org .rhq .modules .plugins .jbossas7 .json .Operation ;
6365import org .rhq .modules .plugins .jbossas7 .json .ReadAttribute ;
6466import org .rhq .modules .plugins .jbossas7 .json .ReadResource ;
67+ import org .rhq .modules .plugins .jbossas7 .json .Remove ;
6568import org .rhq .modules .plugins .jbossas7 .json .Result ;
6669
6770/**
@@ -156,6 +159,21 @@ public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails
156159 return new ArrayList <DeployPackageStep >();
157160 }
158161
162+ /**
163+ * create new Deployer instance for {@link #deployPackages(Set, ContentServices)} code branch which *only* handles package update
164+ * in case of Versioned Deployments
165+ * @see {@link #deployPackages(Set, ContentServices)} and {@link DomainDeploymentComponent#createDeployerForPackageUpdate(String, String, String)}
166+ * @param deploymentName
167+ * @param runtimeName
168+ * @param hash
169+ * @return new Deployer which correctly undeploys original package and then deploys new package
170+ */
171+ protected Deployer createDeployerForPackageUpdate (String deploymentName , String runtimeName , String hash ) {
172+ Deployer deployer = new Deployer (deploymentName , runtimeName , hash , getASConnection ());
173+ deployer .addBeforeDeployStep (new Remove (getAddress ()));
174+ return deployer ;
175+ }
176+
159177 @ Override
160178 public DeployPackagesResponse deployPackages (Set <ResourcePackageDetails > packages , ContentServices contentServices ) {
161179 getLog ().debug ("Starting deployment.." );
@@ -180,7 +198,7 @@ public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> package
180198 }
181199 ResourceType resourceType = context .getResourceType ();
182200
183- getLog ().info ("Deploying " + resourceType .getName () + " Resource with key [" + detail .getKey () + "]..." );
201+ getLog ().info ("Deploying " + resourceType .getName () + " to Resource with key [" + detail .getKey () + "]..." );
184202
185203 try {
186204 contentServices .downloadPackageBits (context .getContentContext (), detail .getKey (), out , true );
@@ -206,19 +224,86 @@ public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> package
206224 String hash = resultNode .get ("BYTES_VALUE" ).getTextValue ();
207225
208226 try {
209- Redeployer redeployer = new Redeployer (detail .getKey ().getName (), hash , getASConnection ());
210- Result result = redeployer .redeployOnServer ();
211- if (result .isRolledBack ()) {
212- response .setOverallRequestResult (ContentResponseResult .FAILURE );
213- response .setOverallRequestErrorMessage ("Rolled Back: " + result .getFailureDescription ());
214- } else {
215- response .setOverallRequestResult (ContentResponseResult .SUCCESS );
216- //we just deployed a different file on the AS7 server, so let's refresh ourselves
217- deploymentFile = determineDeploymentFile ();
218- DeployIndividualPackageResponse packageResponse = new DeployIndividualPackageResponse (detail .getKey (),
219- ContentResponseResult .SUCCESS );
220- response .addPackageResponse (packageResponse );
227+ Result result = null ;
228+ // this deployment can be versioned
229+ // resource deployment name could be deployment-1.0.0.jar, but resourceKey (and name) would be deployment.jar and version 1.0.0
230+ // if there is an attempt to deploy deployment-2.0.0.jar, we need to undeploy deployment-1.0.0.jar and then deploy the new content
231+ // Sipmly redeploy won't work, because deployment-2.0.0.jar is not present on server
232+
233+ //detect whether we're dealing with versioned deployments
234+ if (!AbstractVersionedSubsystemDiscovery .DISABLED ) {
235+
236+ Result readResource = getASConnection ().execute (new ReadResource (getAddress ()));
237+ Map <String , Object > resourceMap = (Map <String , Object >) readResource .getResult ();
238+
239+ String resourceDeploymentName = (String ) resourceMap .get ("name" );
240+ String newDeploymentName = detail .getKey ().getName ();
241+
242+ Matcher versionedResourceMatch = AbstractVersionedSubsystemDiscovery .MATCHER .pattern ().matcher (
243+ resourceDeploymentName );
244+
245+ if (versionedResourceMatch .matches ()) {
246+ // we're dealing with versioned deployment resource
247+ String versionedDeploymentName = versionedResourceMatch .group (1 );
248+
249+ Matcher newContentMatch = AbstractVersionedSubsystemDiscovery .MATCHER .pattern ().matcher (
250+ newDeploymentName );
251+ if (newContentMatch .matches ()) {
252+ // we're strict and only undeploy/deploy in case we're dealing with same deployments (base names match)
253+ if (versionedDeploymentName .equals (newContentMatch .group (1 ))) {
254+
255+ String runtimeName = (String ) resourceMap .get ("runtime-name" );
256+ // preserver runtime-name only if it differs from deploymentName - it was explicitly defined at deploy time
257+ if (runtimeName .equals (resourceDeploymentName )) {
258+ runtimeName = newDeploymentName ;
259+ }
260+ Boolean enabled = (Boolean ) resourceMap .get ("enabled" );
261+ if (enabled == null ) {
262+ enabled = false ; // enabled attribute is null if we're dealing with DomainDeployment
263+ }
264+
265+ Deployer deployer = createDeployerForPackageUpdate (newDeploymentName , runtimeName , hash );
266+ result = deployer .deployToServer (enabled );
267+ } else {
268+ response .setOverallRequestResult (ContentResponseResult .FAILURE );
269+ response
270+ .setOverallRequestErrorMessage ("Failed to update package. Attempt to replace content of versioned resource with key="
271+ + resourceDeploymentName
272+ + " with package key="
273+ + newDeploymentName
274+ + " Given package key does not match." );
275+ }
276+ } else {
277+ response .setOverallRequestResult (ContentResponseResult .FAILURE );
278+ response
279+ .setOverallRequestErrorMessage ("Failed to update package. This resource is versioned deployment and updating it's content by unversioned package is not allowed." );
280+ }
281+
282+ }
283+ // else this resource is not versioned: deployment we default to redeploy
284+
221285 }
286+ if (response .getOverallRequestResult () == null ) {
287+
288+ // if none of undeploy/deploy conditions were met
289+ if (result == null ) {
290+ Redeployer redeployer = new Redeployer (detail .getKey ().getName (), hash , getASConnection ());
291+ result = redeployer .redeployOnServer ();
292+ }
293+
294+ if (result .isRolledBack ()) {
295+ response .setOverallRequestResult (ContentResponseResult .FAILURE );
296+ response .setOverallRequestErrorMessage ("Rolled Back: " + result .getFailureDescription ());
297+ } else {
298+ response .setOverallRequestResult (ContentResponseResult .SUCCESS );
299+ //we just deployed a different file on the AS7 server, so let's refresh ourselves
300+ deploymentFile = determineDeploymentFile ();
301+ DeployIndividualPackageResponse packageResponse = new DeployIndividualPackageResponse (
302+ detail .getKey (), ContentResponseResult .SUCCESS );
303+ response .addPackageResponse (packageResponse );
304+ }
305+ }
306+
222307
223308 } catch (Exception e ) {
224309 response .setOverallRequestResult (ContentResponseResult .FAILURE );
@@ -251,7 +336,8 @@ public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
251336 return Collections .emptySet ();
252337 }
253338
254- String name = getDeploymentName ();
339+ String deploymentName = getDeploymentName ();
340+ String name = String .valueOf (deploymentName );
255341 String sha256 = getSHA256 (deploymentFile );
256342 String version = getVersion (sha256 );
257343
@@ -260,7 +346,7 @@ public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
260346
261347 details .setDisplayVersion (getDisplayVersion (deploymentFile ));
262348 details .setFileCreatedDate (null ); //TODO figure this out from Sigar somehow?
263- details .setFileName (name );
349+ details .setFileName (deploymentName );
264350 details .setFileSize (deploymentFile .length ());
265351 details .setInstallationTimestamp (deploymentFile .lastModified ());
266352 details .setLocation (deploymentFile .getAbsolutePath ());
@@ -462,4 +548,5 @@ private String getDeploymentName() {
462548
463549 return (String ) res .getResult ();
464550 }
551+
465552}
0 commit comments