This repository has been archived by the owner on Jul 11, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BZ 1120418] Initial proof-of-concept for job and step builders for s…
…torage maintenance workflow.
- Loading branch information
Stefan Negrea
committed
Jul 24, 2014
1 parent
23e0ef3
commit 0f1b326
Showing
7 changed files
with
429 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
...enance/src/main/java/org/rhq/server/storage/maintenance/StorageMaintenanceJobFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* RHQ Management Platform | ||
* Copyright (C) 2005-2014 Red Hat, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation version 2 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
package org.rhq.server.storage.maintenance; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.rhq.core.domain.storage.MaintenanceJob; | ||
import org.rhq.core.domain.storage.MaintenanceStep; | ||
import org.rhq.server.storage.maintenance.step.MaintenanceStepFacade; | ||
import org.rhq.server.storage.maintenance.step.ShutdownStorageClient; | ||
import org.rhq.server.storage.maintenance.step.StartStorageClient; | ||
import org.rhq.server.storage.maintenance.step.UpdateStorageNodeEndpoints; | ||
import org.rhq.server.storage.maintenance.step.UpdateStorageNodeEntity; | ||
|
||
/** | ||
* @author Stefan Negrea | ||
* | ||
*/ | ||
public class StorageMaintenanceJobFactory { | ||
|
||
private StorageMaintenanceJobFactory() { | ||
} | ||
|
||
public MaintenanceJob createJob(String operation, String[] existingStorageNodes, String[] affectedNodes, String args) { | ||
MaintenanceJob job = new MaintenanceJob(); | ||
|
||
job.setType(1); | ||
job.setName(operation); | ||
|
||
if (operation.equals("NodeChangeAddress")) { | ||
job.setSteps(createNodeChangeAddressSteps(job, existingStorageNodes, affectedNodes)); | ||
} | ||
|
||
return job; | ||
} | ||
|
||
public List<MaintenanceStep> createNodeChangeAddressSteps(MaintenanceJob job, String[] existingNodes, | ||
String[] affectedNodes) { | ||
|
||
List<MaintenanceStep> steps = new ArrayList<MaintenanceStep>(); | ||
|
||
if (existingNodes.length == 1) { | ||
int stepCount = 0; | ||
|
||
MaintenanceStepFacade stepBuilder = new UpdateStorageNodeEntity(); | ||
steps.add(stepBuilder.build(job, stepCount++, existingNodes, affectedNodes[0])); | ||
|
||
stepBuilder = new ShutdownStorageClient(); | ||
steps.add(stepBuilder.build(job, stepCount++, existingNodes, affectedNodes[0])); | ||
|
||
stepBuilder = new UpdateStorageNodeEndpoints(); | ||
steps.add(stepBuilder.build(job, stepCount++, existingNodes, affectedNodes[0])); | ||
|
||
stepBuilder = new StartStorageClient(); | ||
steps.add(stepBuilder.build(job, stepCount++, existingNodes, affectedNodes[0])); | ||
} | ||
|
||
return steps; | ||
} | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
...ntenance/src/main/java/org/rhq/server/storage/maintenance/step/MaintenanceStepFacade.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* RHQ Management Platform | ||
* Copyright (C) 2005-2014 Red Hat, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation version 2 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
package org.rhq.server.storage.maintenance.step; | ||
|
||
import org.rhq.core.domain.storage.MaintenanceJob; | ||
import org.rhq.core.domain.storage.MaintenanceStep; | ||
|
||
/** | ||
* @author Stefan Negrea | ||
* | ||
*/ | ||
public interface MaintenanceStepFacade { | ||
|
||
void execute(MaintenanceStep maintenanceStep) throws Exception; | ||
|
||
MaintenanceStep build(MaintenanceJob job, int stepNumber, String[] existingNodes, String affectedNode); | ||
} |
55 changes: 55 additions & 0 deletions
55
...ntenance/src/main/java/org/rhq/server/storage/maintenance/step/ShutdownStorageClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* RHQ Management Platform | ||
* Copyright (C) 2005-2014 Red Hat, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation version 2 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
package org.rhq.server.storage.maintenance.step; | ||
|
||
import javax.ejb.EJB; | ||
|
||
import org.rhq.core.domain.storage.MaintenanceJob; | ||
import org.rhq.core.domain.storage.MaintenanceStep; | ||
import org.rhq.core.domain.storage.MaintenanceStep.Type; | ||
import org.rhq.enterprise.server.storage.StorageClientManager; | ||
|
||
/** | ||
* @author Stefan Negrea | ||
* | ||
*/ | ||
public class ShutdownStorageClient implements MaintenanceStepFacade { | ||
|
||
@EJB | ||
private StorageClientManager storageClientManager; | ||
|
||
@Override | ||
public void execute(MaintenanceStep maintenanceStep) { | ||
storageClientManager.shutdown(); | ||
} | ||
|
||
@Override | ||
public MaintenanceStep build(MaintenanceJob job, int stepNumber, String[] existingNodes, String affectedNode) { | ||
MaintenanceStep step = new MaintenanceStep(); | ||
|
||
step.setStep(stepNumber) | ||
.setName(ShutdownStorageClient.class.getSimpleName()) | ||
.setType(Type.ServerUpdate) | ||
.setSequential(true) | ||
.setTimeout(1000) | ||
.setMaintenanceJob(job); | ||
|
||
return step; | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
...maintenance/src/main/java/org/rhq/server/storage/maintenance/step/StartStorageClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* RHQ Management Platform | ||
* Copyright (C) 2005-2014 Red Hat, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation version 2 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
package org.rhq.server.storage.maintenance.step; | ||
|
||
import javax.ejb.EJB; | ||
|
||
import org.rhq.core.domain.storage.MaintenanceJob; | ||
import org.rhq.core.domain.storage.MaintenanceStep; | ||
import org.rhq.core.domain.storage.MaintenanceStep.Type; | ||
import org.rhq.enterprise.server.storage.StorageClientManager; | ||
|
||
/** | ||
* @author Stefan Negrea | ||
* | ||
*/ | ||
public class StartStorageClient implements MaintenanceStepFacade { | ||
|
||
@EJB | ||
private StorageClientManager storageClientManager; | ||
|
||
@Override | ||
public void execute(MaintenanceStep maintenanceStep) { | ||
storageClientManager.init(); | ||
} | ||
|
||
@Override | ||
public MaintenanceStep build(MaintenanceJob job, int stepNumber, String[] existingNodes, String affectedNode) { | ||
MaintenanceStep step = new MaintenanceStep(); | ||
|
||
step.setStep(stepNumber) | ||
.setName(StartStorageClient.class.getSimpleName()) | ||
.setType(Type.ServerUpdate) | ||
.setSequential(true) | ||
.setTimeout(1000) | ||
.setMaintenanceJob(job); | ||
|
||
return step; | ||
} | ||
} |
121 changes: 121 additions & 0 deletions
121
...nce/src/main/java/org/rhq/server/storage/maintenance/step/UpdateStorageNodeEndpoints.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* RHQ Management Platform | ||
* Copyright (C) 2005-2014 Red Hat, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation version 2 of the License. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
package org.rhq.server.storage.maintenance.step; | ||
|
||
import javax.ejb.EJB; | ||
|
||
import org.rhq.core.domain.cloud.StorageNode; | ||
import org.rhq.core.domain.common.JobTrigger; | ||
import org.rhq.core.domain.configuration.Configuration; | ||
import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria; | ||
import org.rhq.core.domain.operation.OperationRequestStatus; | ||
import org.rhq.core.domain.operation.ResourceOperationHistory; | ||
import org.rhq.core.domain.operation.bean.ResourceOperationSchedule; | ||
import org.rhq.core.domain.resource.Resource; | ||
import org.rhq.core.domain.storage.MaintenanceJob; | ||
import org.rhq.core.domain.storage.MaintenanceStep; | ||
import org.rhq.core.domain.storage.MaintenanceStep.Type; | ||
import org.rhq.core.domain.util.PageControl; | ||
import org.rhq.core.domain.util.PageList; | ||
import org.rhq.enterprise.server.auth.SubjectManagerBean; | ||
import org.rhq.enterprise.server.cloud.StorageNodeManagerBean; | ||
import org.rhq.enterprise.server.operation.OperationManagerBean; | ||
|
||
/** | ||
* @author Stefan Negrea | ||
* | ||
*/ | ||
public class UpdateStorageNodeEndpoints implements MaintenanceStepFacade { | ||
|
||
@EJB | ||
private StorageNodeManagerBean storageNodeManager; | ||
|
||
@EJB | ||
private SubjectManagerBean subjectManager; | ||
|
||
@EJB | ||
private OperationManagerBean operationManager; | ||
|
||
@Override | ||
public void execute(MaintenanceStep maintenanceStep) throws Exception { | ||
|
||
StorageNode storageNode = storageNodeManager.findStorageNodeByAddress(maintenanceStep.getNodeAddress()); | ||
Resource storageNodeResource = storageNode.getResource(); | ||
//scheduling the operation | ||
long operationStartTime = System.currentTimeMillis(); | ||
|
||
ResourceOperationSchedule newSchedule = new ResourceOperationSchedule(); | ||
newSchedule.setJobTrigger(JobTrigger.createNowTrigger()); | ||
newSchedule.setResource(storageNodeResource); | ||
newSchedule.setOperationName("updateEndpoints"); | ||
newSchedule.setDescription("Run by StorageNodeManagerBean"); | ||
newSchedule.setParameters(new Configuration()); | ||
|
||
storageNodeManager.scheduleOperationInNewTransaction(subjectManager.getOverlord(), newSchedule); | ||
|
||
//waiting for the operation result then return it | ||
int iteration = 0; | ||
boolean successResultFound = false; | ||
while (iteration < 10 && !successResultFound) { | ||
ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria(); | ||
criteria.addFilterResourceIds(storageNodeResource.getId()); | ||
criteria.addFilterStartTime(operationStartTime); | ||
criteria.addFilterOperationName("updateEndpoints"); | ||
criteria.addFilterStatus(OperationRequestStatus.SUCCESS); | ||
criteria.setPageControl(PageControl.getUnlimitedInstance()); | ||
|
||
PageList<ResourceOperationHistory> results = operationManager.findResourceOperationHistoriesByCriteria( | ||
subjectManager.getOverlord(), criteria); | ||
|
||
if (results != null && results.size() > 0) { | ||
successResultFound = true; | ||
} | ||
|
||
if (successResultFound) { | ||
break; | ||
} else { | ||
try { | ||
Thread.sleep(100); | ||
} catch (Exception e) { | ||
} | ||
} | ||
|
||
iteration++; | ||
} | ||
|
||
if (!successResultFound) { | ||
throw new Exception(); | ||
} | ||
} | ||
|
||
@Override | ||
public MaintenanceStep build(MaintenanceJob job, int stepNumber, String[] existingNodes, String affectedNode) { | ||
MaintenanceStep step = new MaintenanceStep(); | ||
step.setStep(stepNumber) | ||
.setName(UpdateStorageNodeEndpoints.class.getSimpleName()) | ||
.setNodeAddress(affectedNode) | ||
.setType(Type.ResourceOperation) | ||
.setSequential(true) | ||
.setTimeout(1000) | ||
.setMaintenanceJob(job); | ||
|
||
return step; | ||
} | ||
|
||
} |
Oops, something went wrong.
0f1b326
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some things we need to discuss and change. First, this commit introduces a circular dependency at compile time. We already have a server/jar --> storage-maintenance maven dependency, and now we have a storage-maintenance --> server/jar dependency. That won't work.
I am -1 on
StorageMaintenanceJobFactory
as it exists so far. We can separate and decouple the code for building jobs, i.e., the job builder from the factory that produces the job builders. This provides a better separation of concerns that facilitates testing and makes it easier for the code to evolve independently.MaintenanceStep.nodeAddress
should be replaced with the StorageNode for a couple reasons. First, since the address can change, future jobs could break as they would no longer have the right address. Secondly, we need the StorageNode and its associated resource for executing operations.I think that the JPA mapping for
MaintenanceJob.steps
is slightly wrong. I think it is missing an@OrderColumn
. Without it, I do not think that order will necessarily be preserved.The MaintenanceStepFacade impls have
EJB
dependencies. I don't think this will work since they are neither EJBs themselves nor CDI beans. And we unfortunately still cannot use CDI. They also do not store the arguments for the resource or server operation to be executed.UpdateStorageNodeEndpoints
has a bunch of code for executing and waiting for the results of a resource operation. That is or should be boiler plate code. It will be necessary for a growing number of maintenance steps. This logic should be performed byStorageClusterMaintenanceManagerBean
. That way it is encapsulated in a single place and the kept of the maintenance step and step building code.I put together a small PoC jsanda@b46df40 that shows what I had in mind and addresses some of the issues I have mentioned. It uses a more strongly typed approach for executing server side operations; however, I am starting to see more benefits of an embedded script approach.