Commit e5a31864 authored by Peter Harrison's avatar Peter Harrison

Merge pull request #29 from cheetah100/experimental

Experimental - Pushing back changes from Experimental.
parents 8439682d 609124ab
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<type>jar</type> <type>jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId> <artifactId>spring-security-core</artifactId>
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId> <artifactId>spring-security-config</artifactId>
<version>${spring.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
...@@ -316,7 +316,7 @@ ...@@ -316,7 +316,7 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.2.5</version> <version>4.3.6</version>
</dependency> </dependency>
<dependency> <dependency>
...@@ -363,6 +363,30 @@ ...@@ -363,6 +363,30 @@
<version>2.2.1</version> <version>2.2.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-elasticloadbalancing</artifactId>
<version>1.10.37</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-iam</artifactId>
<version>1.10.37</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cloudfront</artifactId>
<version>1.10.37</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream</groupId>
<artifactId>sjsxp</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies> </dependencies>
...@@ -415,4 +439,36 @@ ...@@ -415,4 +439,36 @@
</plugins> </plugins>
</build> </build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<configuration>
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
</configuration>
</plugin>
</plugins>
</reporting>
</project> </project>
...@@ -100,17 +100,11 @@ public class AutomationEngine { ...@@ -100,17 +100,11 @@ public class AutomationEngine {
try { try {
card = cardController.getCard(cardHolder.getBoardId(), card = cardController.getCard(cardHolder.getBoardId(),
null, cardHolder.getCardId(), "full"); null, cardHolder.getCardId(), "full");
board = boardsCache.getItem(cardHolder.getBoardId());
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
LOG.info("Resource no longer exists: " + cardHolder.toString()); LOG.info("Resource no longer exists: " + cardHolder.toString());
return; return;
} }
if (board == null) {
LOG.warn("Board Not Found: " + cardHolder.getBoardId());
return;
}
Map<String,Rule> rules = getRulesFromBoard(cardHolder.getBoardId()); Map<String,Rule> rules = getRulesFromBoard(cardHolder.getBoardId());
LOG.info("Automation Examining :" + card.getPath()); LOG.info("Automation Examining :" + card.getPath());
...@@ -121,7 +115,7 @@ public class AutomationEngine { ...@@ -121,7 +115,7 @@ public class AutomationEngine {
Collection<CardEvent> alerts = cardController.getAlerts(card.getBoard(), card.getPhase(), card.getId().toString()); Collection<CardEvent> alerts = cardController.getAlerts(card.getBoard(), card.getPhase(), card.getId().toString());
for( CardEvent alert : alerts){ for( CardEvent alert : alerts){
if(alert==null){ if(alert==null){
LOG.equals("Alert NULL inside Loop"); LOG.error("Alert NULL inside Loop");
} }
if("alert".equals(alert.getLevel())){ if("alert".equals(alert.getLevel())){
...@@ -698,10 +692,6 @@ public class AutomationEngine { ...@@ -698,10 +692,6 @@ public class AutomationEngine {
// Get Rule. // Get Rule.
Rule rule = ruleCache.getItem(boardId, ruleId); Rule rule = ruleCache.getItem(boardId, ruleId);
if(rule==null){
LOG.warn("Execute Actions: Rule Not Found: "+ boardId + "/" + ruleId);
return;
}
List<Action> sortedActionList = getSortedActions(rule.getActions()); List<Action> sortedActionList = getSortedActions(rule.getActions());
...@@ -771,37 +761,42 @@ public class AutomationEngine { ...@@ -771,37 +761,42 @@ public class AutomationEngine {
private void raiseAlertOnError(Throwable e, Rule rule, Action action, Card card) throws Exception{ private void raiseAlertOnError(Throwable e, Rule rule, Action action, Card card) throws Exception{
String causeMessage = ""; StringBuilder message = new StringBuilder();
message.append(rule.getName());
message.append(" ");
message.append(action.getName());
message.append(" calling: ");
message.append(action.getType());
message.append(".");
message.append(action.getResource());
message.append(".");
message.append(action.getMethod());
message.append(" caused ");
Throwable cause = e; Throwable cause = e;
while(cause!=null){ while(cause!=null){
if( cause.getMessage()!=null){ if( cause.getMessage()!=null){
causeMessage = causeMessage + "(" + cause.getMessage() + ") "; message.append("(");
message.append(cause.getMessage());
message.append(") ");
} }
cause = cause.getCause(); cause = cause.getCause();
} }
String message = rule.getName()
+ " " + action.getName()
+ " calling: " + action.getType()
+ "." + action.getResource()
+ "." + action.getMethod()
+ " caused " + causeMessage;
if(card!=null){ if(card!=null){
if( cardController!=null){ if( cardController!=null){
cardController.saveAlert( cardController.saveAlert(
card.getBoard(), card.getBoard(),
card.getPhase(), card.getPhase(),
card.getId().toString(), card.getId().toString(),
message, message.toString(),
"alert"); "alert");
} }
LOG.warn( "Automation Exception - Card " + card.getId() + " " + message, e); LOG.warn( "Automation Exception - Card " + card.getId() + " " + message.toString(), e);
} else { } else {
LOG.warn( "Automation Exception " + message, e); LOG.warn( "Automation Exception " + message.toString(), e);
} }
} }
private void outputContext( Map<String,Object> context){ private void outputContext( Map<String,Object> context){
......
...@@ -115,7 +115,7 @@ public class ClusterManager { ...@@ -115,7 +115,7 @@ public class ClusterManager {
*/ */
@Scheduled( fixedDelay=30000l ) @Scheduled( fixedDelay=30000l )
public void pollLeader() throws Exception{ public void pollLeader() throws Exception{
if(!this.leader){ if(!isLeader()){
this.executeChallenge(); this.executeChallenge();
} }
} }
...@@ -137,28 +137,28 @@ public class ClusterManager { ...@@ -137,28 +137,28 @@ public class ClusterManager {
Message coupMessage = coupSync.receiveMessage(10000l); Message coupMessage = coupSync.receiveMessage(10000l);
boolean newLeader = (coupMessage==null); boolean newLeader = (coupMessage==null);
if( this.leader!=newLeader){ if( isLeader()!=newLeader){
if(newLeader){ if(newLeader){
LOG.warn("FAILOVER: Node promoted to MASTER."); LOG.warn("FAILOVER: Node promoted to MASTER.");
this.leader = true; setLeader(true);
this.jcrObserver.start(); this.jcrObserver.start();
this.timerManager.startup(); this.timerManager.startup();
} else { } else {
LOG.warn("FAILOVER: Node demoted to worker."); LOG.warn("FAILOVER: Node demoted to worker.");
this.leader = false; setLeader(false);
this.jcrObserver.stop(); this.jcrObserver.stop();
this.timerManager.stopAll(); this.timerManager.stopAll();
} }
} }
return this.leader; return isLeader();
} }
public void setLeader(boolean leader) { public synchronized void setLeader(boolean leader) {
this.leader = leader; this.leader = leader;
} }
public boolean isLeader() { public synchronized boolean isLeader() {
return leader; return leader;
} }
......
...@@ -30,6 +30,7 @@ import java.util.Map; ...@@ -30,6 +30,7 @@ import java.util.Map;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import nz.net.orcon.kanban.controllers.BoardsCache; import nz.net.orcon.kanban.controllers.BoardsCache;
import nz.net.orcon.kanban.controllers.ResourceNotFoundException;
import nz.net.orcon.kanban.controllers.RuleCache; import nz.net.orcon.kanban.controllers.RuleCache;
import nz.net.orcon.kanban.model.Condition; import nz.net.orcon.kanban.model.Condition;
import nz.net.orcon.kanban.model.ConditionType; import nz.net.orcon.kanban.model.ConditionType;
...@@ -104,10 +105,6 @@ public class TimerManager { ...@@ -104,10 +105,6 @@ public class TimerManager {
Map<String, String> rules; Map<String, String> rules;
try { try {
rules = ruleCache.list(boardId,""); rules = ruleCache.list(boardId,"");
if( rules==null){
LOG.warn("Board Rules Not Found when Loading Timer: " + boardId);
return;
}
} catch (javax.jcr.PathNotFoundException e ){ } catch (javax.jcr.PathNotFoundException e ){
LOG.info("No Rule for Board: "+ boardId); LOG.info("No Rule for Board: "+ boardId);
return; return;
...@@ -121,14 +118,18 @@ public class TimerManager { ...@@ -121,14 +118,18 @@ public class TimerManager {
// Start Timers // Start Timers
for( String ruleId : rules.keySet()){ for( String ruleId : rules.keySet()){
Rule rule = ruleCache.getItem(boardId,ruleId); try {
if(null != rule.getAutomationConditions()){ Rule rule = ruleCache.getItem(boardId,ruleId);
for( Condition condition : rule.getAutomationConditions().values()) { if(null != rule.getAutomationConditions()){
if( ConditionType.TIMER.equals(condition.getConditionType())){ for( Condition condition : rule.getAutomationConditions().values()) {
activateTimer( boardId, rule.getId(), condition.getValue()); if( ConditionType.TIMER.equals(condition.getConditionType())){
LOG.info("Timer Loaded: " + boardId + "." + rule.getId()); activateTimer( boardId, rule.getId(), condition.getValue());
LOG.info("Timer Loaded: " + boardId + "." + rule.getId());
}
} }
} }
} catch(ResourceNotFoundException e){
LOG.warn("Rule not found: " + boardId + "." + ruleId);
} }
} }
} }
......
package nz.net.orcon.kanban.automation.actions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.amazonaws.AmazonWebServiceClient;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cloudfront.AmazonCloudFrontClient;
import com.amazonaws.services.cloudfront.model.CookiePreference;
import com.amazonaws.services.cloudfront.model.CreateDistributionRequest;
import com.amazonaws.services.cloudfront.model.CreateDistributionResult;
import com.amazonaws.services.cloudfront.model.CustomOriginConfig;
import com.amazonaws.services.cloudfront.model.DefaultCacheBehavior;
import com.amazonaws.services.cloudfront.model.DistributionConfig;
import com.amazonaws.services.cloudfront.model.ForwardedValues;
import com.amazonaws.services.cloudfront.model.Headers;
import com.amazonaws.services.cloudfront.model.Origin;
import com.amazonaws.services.cloudfront.model.OriginProtocolPolicy;
import com.amazonaws.services.cloudfront.model.Origins;
import com.amazonaws.services.cloudfront.model.TrustedSigners;
import com.amazonaws.services.cloudfront.model.ViewerCertificate;
import com.amazonaws.services.cloudfront.model.ViewerProtocolPolicy;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersResult;
import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription;
import com.amazonaws.services.elasticloadbalancing.model.SetLoadBalancerListenerSSLCertificateRequest;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClient;
import com.amazonaws.services.identitymanagement.model.GetAccountSummaryResult;
import com.amazonaws.services.identitymanagement.model.ListServerCertificatesResult;
import com.amazonaws.services.identitymanagement.model.ServerCertificateMetadata;
import com.amazonaws.services.identitymanagement.model.UploadServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.UploadServerCertificateResult;
public class AwsAutomationAction {
@Autowired
private AmazonElasticLoadBalancingClient loadBalanceClient;
@Autowired
private AmazonIdentityManagementClient identityClient;
@Autowired
private AmazonCloudFrontClient cloudFrontClient;
public List<ServerCertificateMetadata> getCertificates(){
ListServerCertificatesResult listSigningCertificates = identityClient.listServerCertificates();
return listSigningCertificates.getServerCertificateMetadataList();
}
public String loadSSLCertificate(
String certificateName,
String certificate,
String privateKey,
String path){
String certificateId = this.getCertificateId(certificateName);
if(certificateId==null){
UploadServerCertificateRequest certificateRequest =
new UploadServerCertificateRequest( certificateName, certificate, privateKey);
certificateRequest.setPath(path);
UploadServerCertificateResult uploadServerCertificate =
getIdentityClient().uploadServerCertificate(certificateRequest);
certificateId = uploadServerCertificate.getServerCertificateMetadata().getServerCertificateId();
}
return certificateId;
}
public void setLoadBalancerCertificate( String loadBalancerName, String certificateId, Integer port ){
System.out.println( "LB CertID: " + certificateId);
this.loadBalanceClient.setRegion(Region.getRegion(Regions.AP_SOUTHEAST_2));
SetLoadBalancerListenerSSLCertificateRequest lbRequest =
new SetLoadBalancerListenerSSLCertificateRequest(
loadBalancerName,
port,
certificateId);
getLoadBalanceClient().setLoadBalancerListenerSSLCertificate(lbRequest);
}
public boolean isSSLCertificateLoaded( String certificateName ){
List<ServerCertificateMetadata> certificates = this.getCertificates();
for( ServerCertificateMetadata certificate : certificates){
if(certificate.getServerCertificateName().equals(certificateName)) {
return true;
}
}
return false;
}
public String getCertificateId( String certificateName){
List<ServerCertificateMetadata> certificates = this.getCertificates();
for( ServerCertificateMetadata certificate : certificates){
if(certificate.getServerCertificateName().equals(certificateName)) {
return certificate.getServerCertificateId();
}
}
return null;
}
public Collection<String> getLoadBalancerList(){
DescribeLoadBalancersResult loadBalancers = this.loadBalanceClient.describeLoadBalancers();
System.out.println(loadBalancers.toString());
Collection returnList = new ArrayList<String>();
List<LoadBalancerDescription> loadBalancerDescriptions = loadBalancers.getLoadBalancerDescriptions();
for( LoadBalancerDescription desc : loadBalancerDescriptions){
returnList.add(desc.getDNSName());
}
return returnList;
}
public String createCloudFrontDistribution(
String domainName,
String certificateId,
String originId,
String callerReference) {
CreateDistributionRequest createDistributionRequest = new CreateDistributionRequest();
DistributionConfig distributionConfig = new DistributionConfig();
DefaultCacheBehavior defaultCacheBehavior = new DefaultCacheBehavior();
ViewerCertificate viewerCertificate = new ViewerCertificate();
ForwardedValues forwardedValues = new ForwardedValues();
Headers headers = new Headers();
TrustedSigners trustedSigners = new TrustedSigners();
CookiePreference cookies = new CookiePreference();
Origin origin = new Origin();
Origins origins = new Origins();
Collection<Origin> items = new ArrayList<Origin>();
CustomOriginConfig customOriginConfig = new CustomOriginConfig();
// Origins
customOriginConfig.setHTTPPort(80);
customOriginConfig.setHTTPSPort(443);
customOriginConfig.setOriginProtocolPolicy(OriginProtocolPolicy.MatchViewer);
origin.setDomainName(domainName);
origin.setId(originId);
origin.setOriginPath("");
origin.setCustomOriginConfig(customOriginConfig);
items.add(origin);
origins.setItems(items);
origins.setQuantity(1);
// Forwarded Values & Headers & Cookies
cookies.setForward("all");
Collection<String> headerItems = new ArrayList<String>();
headers.setItems(headerItems);
headers.setQuantity(0);
forwardedValues.setHeaders(headers);
forwardedValues.setQueryString(false);
forwardedValues.setCookies(cookies);
// Trusted Signers
trustedSigners.setEnabled(false);
trustedSigners.setQuantity(0);
// Viewer Certificate
viewerCertificate.setIAMCertificateId(certificateId);
// Default Cache BEhaviour
defaultCacheBehavior.setMinTTL(30l);
defaultCacheBehavior.setViewerProtocolPolicy(ViewerProtocolPolicy.AllowAll);
defaultCacheBehavior.setForwardedValues(forwardedValues);
defaultCacheBehavior.setTargetOriginId("");
defaultCacheBehavior.setTrustedSigners(trustedSigners);
// Distribution Config
distributionConfig.setOrigins(origins);
distributionConfig.setViewerCertificate(viewerCertificate);
distributionConfig.setCallerReference(callerReference);
distributionConfig.setDefaultCacheBehavior(defaultCacheBehavior);
distributionConfig.setEnabled(true);
distributionConfig.setComment("no comment");
distributionConfig.setDefaultRootObject("");
createDistributionRequest.setDistributionConfig(distributionConfig);
CreateDistributionResult createDistribution
= this.cloudFrontClient.createDistribution(createDistributionRequest);
return createDistribution.getLocation();
}
public Map<String, Integer> getAccountSummary(){
GetAccountSummaryResult accountSummary = getIdentityClient().getAccountSummary();
Map<String, Integer> summaryMap = accountSummary.getSummaryMap();
return summaryMap;
}
public AmazonElasticLoadBalancingClient getLoadBalanceClient() {
return loadBalanceClient;
}
public void setLoadBalanceClient(AmazonElasticLoadBalancingClient loadBalanceClient) {
this.loadBalanceClient = loadBalanceClient;
}
public AmazonIdentityManagementClient getIdentityClient() {
return identityClient;
}
public void setIdentityClient(AmazonIdentityManagementClient identityClient) {
this.identityClient = identityClient;
}
public AmazonCloudFrontClient getCloudFrontClient() {
return cloudFrontClient;
}
public void setCloudFrontClient(AmazonCloudFrontClient cloudFrontClient) {
this.cloudFrontClient = cloudFrontClient;
}
}
...@@ -62,6 +62,8 @@ import org.springframework.web.bind.annotation.RequestMethod; ...@@ -62,6 +62,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.amazonaws.util.StringUtils;
/** /**
* *
*/ */
...@@ -71,7 +73,7 @@ public class BoardController { ...@@ -71,7 +73,7 @@ public class BoardController {
private static final Logger logger = LoggerFactory.getLogger(BoardController.class); private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
public static String BOARD = "BOARD"; public static final String BOARD = "BOARD";
@Resource(name="ocmFactory") @Resource(name="ocmFactory")
OcmMapperFactory ocmFactory; OcmMapperFactory ocmFactory;
...@@ -407,11 +409,11 @@ public class BoardController { ...@@ -407,11 +409,11 @@ public class BoardController {
detailFilter = "(jcr:contains(@detail,'${detail}'))".replaceAll("\\$\\{detail\\}", detail); detailFilter = "(jcr:contains(@detail,'${detail}'))".replaceAll("\\$\\{detail\\}", detail);
} }
if(categoryFilter!="" && detailFilter!=""){ if( !StringUtils.isNullOrEmpty(categoryFilter) && !StringUtils.isNullOrEmpty(detailFilter)){
qmFilter.addJCRExpression( categoryFilter + " or " + detailFilter); qmFilter.addJCRExpression( categoryFilter + " or " + detailFilter);
} else if (categoryFilter!="" && detailFilter=="") { } else if ( !StringUtils.isNullOrEmpty(categoryFilter) && StringUtils.isNullOrEmpty(detailFilter)) {
qmFilter.addJCRExpression( categoryFilter ); qmFilter.addJCRExpression( categoryFilter );
} else if (categoryFilter=="" && detailFilter!="") { } else if (StringUtils.isNullOrEmpty(categoryFilter) && !StringUtils.isNullOrEmpty(detailFilter)) {
qmFilter.addJCRExpression( detailFilter ); qmFilter.addJCRExpression( detailFilter );
} }
......
/** /**
* GRAVITY WORKFLOW AUTOMATION * GRAVITY WORKFLOW AUTOMATION
* (C) Copyright 2015 Orcon Limited * (C) Copyright 2015 Orcon Limited
* (C) Copyright 2015 Peter Harrrison
* *
* This file is part of Gravity Workflow Automation. * This file is part of Gravity Workflow Automation.
* *
...@@ -25,7 +26,7 @@ import java.util.Map; ...@@ -25,7 +26,7 @@ import java.util.Map;
public interface Cache<T> { public interface Cache<T> {
public void invalidate( String itemId ); public void invalidate( String... itemIds );
public T getItem(String... itemIds) throws Exception; public T getItem(String... itemIds) throws Exception;
......
/** /**
* GRAVITY WORKFLOW AUTOMATION * GRAVITY WORKFLOW AUTOMATION
* (C) Copyright 2015 Orcon Limited * (C) Copyright 2015 Orcon Limited
* (C) Copyright 2015 Peter Harrison
* *
* This file is part of Gravity Workflow Automation. * This file is part of Gravity Workflow Automation.