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 @@
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
......@@ -89,7 +89,7 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
</dependency>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
......@@ -316,7 +316,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.5</version>
<version>4.3.6</version>
</dependency>
<dependency>
......@@ -363,6 +363,30 @@
<version>2.2.1</version>
<scope>compile</scope>
</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>
......@@ -415,4 +439,36 @@
</plugins>
</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>
......@@ -100,17 +100,11 @@ public class AutomationEngine {
try {
card = cardController.getCard(cardHolder.getBoardId(),
null, cardHolder.getCardId(), "full");
board = boardsCache.getItem(cardHolder.getBoardId());
} catch (ResourceNotFoundException e) {
LOG.info("Resource no longer exists: " + cardHolder.toString());
return;
}
if (board == null) {
LOG.warn("Board Not Found: " + cardHolder.getBoardId());
return;
}
Map<String,Rule> rules = getRulesFromBoard(cardHolder.getBoardId());
LOG.info("Automation Examining :" + card.getPath());
......@@ -121,7 +115,7 @@ public class AutomationEngine {
Collection<CardEvent> alerts = cardController.getAlerts(card.getBoard(), card.getPhase(), card.getId().toString());
for( CardEvent alert : alerts){
if(alert==null){
LOG.equals("Alert NULL inside Loop");
LOG.error("Alert NULL inside Loop");
}
if("alert".equals(alert.getLevel())){
......@@ -698,10 +692,6 @@ public class AutomationEngine {
// Get Rule.
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());
......@@ -771,37 +761,42 @@ public class AutomationEngine {
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;
while(cause!=null){
if( cause.getMessage()!=null){
causeMessage = causeMessage + "(" + cause.getMessage() + ") ";
message.append("(");
message.append(cause.getMessage());
message.append(") ");
}
cause = cause.getCause();
}
String message = rule.getName()
+ " " + action.getName()
+ " calling: " + action.getType()
+ "." + action.getResource()
+ "." + action.getMethod()
+ " caused " + causeMessage;
if(card!=null){
if( cardController!=null){
cardController.saveAlert(
card.getBoard(),
card.getPhase(),
card.getId().toString(),
message,
message.toString(),
"alert");
}
LOG.warn( "Automation Exception - Card " + card.getId() + " " + message, e);
LOG.warn( "Automation Exception - Card " + card.getId() + " " + message.toString(), e);
} else {
LOG.warn( "Automation Exception " + message, e);
LOG.warn( "Automation Exception " + message.toString(), e);
}
}
private void outputContext( Map<String,Object> context){
......
......@@ -115,7 +115,7 @@ public class ClusterManager {
*/
@Scheduled( fixedDelay=30000l )
public void pollLeader() throws Exception{
if(!this.leader){
if(!isLeader()){
this.executeChallenge();
}
}
......@@ -137,28 +137,28 @@ public class ClusterManager {
Message coupMessage = coupSync.receiveMessage(10000l);
boolean newLeader = (coupMessage==null);
if( this.leader!=newLeader){
if( isLeader()!=newLeader){
if(newLeader){
LOG.warn("FAILOVER: Node promoted to MASTER.");
this.leader = true;
setLeader(true);
this.jcrObserver.start();
this.timerManager.startup();
} else {
LOG.warn("FAILOVER: Node demoted to worker.");
this.leader = false;
setLeader(false);
this.jcrObserver.stop();
this.timerManager.stopAll();
}
}
return this.leader;
return isLeader();
}
public void setLeader(boolean leader) {
public synchronized void setLeader(boolean leader) {
this.leader = leader;
}
public boolean isLeader() {
public synchronized boolean isLeader() {
return leader;
}
......
......@@ -30,6 +30,7 @@ import java.util.Map;
import javax.annotation.PreDestroy;
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.model.Condition;
import nz.net.orcon.kanban.model.ConditionType;
......@@ -104,10 +105,6 @@ public class TimerManager {
Map<String, String> rules;
try {
rules = ruleCache.list(boardId,"");
if( rules==null){
LOG.warn("Board Rules Not Found when Loading Timer: " + boardId);
return;
}
} catch (javax.jcr.PathNotFoundException e ){
LOG.info("No Rule for Board: "+ boardId);
return;
......@@ -121,14 +118,18 @@ public class TimerManager {
// Start Timers
for( String ruleId : rules.keySet()){
Rule rule = ruleCache.getItem(boardId,ruleId);
if(null != rule.getAutomationConditions()){
for( Condition condition : rule.getAutomationConditions().values()) {
if( ConditionType.TIMER.equals(condition.getConditionType())){
activateTimer( boardId, rule.getId(), condition.getValue());
LOG.info("Timer Loaded: " + boardId + "." + rule.getId());
try {
Rule rule = ruleCache.getItem(boardId,ruleId);
if(null != rule.getAutomationConditions()){
for( Condition condition : rule.getAutomationConditions().values()) {
if( ConditionType.TIMER.equals(condition.getConditionType())){
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;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.amazonaws.util.StringUtils;
/**
*
*/
......@@ -71,7 +73,7 @@ public class BoardController {
private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
public static String BOARD = "BOARD";
public static final String BOARD = "BOARD";
@Resource(name="ocmFactory")
OcmMapperFactory ocmFactory;
......@@ -407,11 +409,11 @@ public class BoardController {
detailFilter = "(jcr:contains(@detail,'${detail}'))".replaceAll("\\$\\{detail\\}", detail);
}
if(categoryFilter!="" && detailFilter!=""){
if( !StringUtils.isNullOrEmpty(categoryFilter) && !StringUtils.isNullOrEmpty(detailFilter)){
qmFilter.addJCRExpression( categoryFilter + " or " + detailFilter);
} else if (categoryFilter!="" && detailFilter=="") {
} else if ( !StringUtils.isNullOrEmpty(categoryFilter) && StringUtils.isNullOrEmpty(detailFilter)) {
qmFilter.addJCRExpression( categoryFilter );
} else if (categoryFilter=="" && detailFilter!="") {
} else if (StringUtils.isNullOrEmpty(categoryFilter) && !StringUtils.isNullOrEmpty(detailFilter)) {
qmFilter.addJCRExpression( detailFilter );
}
......
/**
* GRAVITY WORKFLOW AUTOMATION
* (C) Copyright 2015 Orcon Limited
* (C) Copyright 2015 Peter Harrrison
*
* This file is part of Gravity Workflow Automation.
*
......@@ -25,7 +26,7 @@ import java.util.Map;
public interface Cache<T> {
public void invalidate( String itemId );
public void invalidate( String... itemIds );
public T getItem(String... itemIds) throws Exception;
......
/**
* GRAVITY WORKFLOW AUTOMATION
* (C) Copyright 2015 Orcon Limited
* (C) Copyright 2015 Peter Harrison
*
* This file is part of Gravity Workflow Automation.
*
......@@ -31,12 +32,21 @@ abstract public class CacheImpl<T> implements Cache<T> {
private Map<String, T> cacheMap = new ConcurrentHashMap<String,T>();
private Map<String,String> cacheList = null;
private Map<String,Map<String,String>> cacheList = new ConcurrentHashMap<String, Map<String,String>>();
@Override
public void invalidate(String itemId) {
this.cacheMap.remove(itemId);
this.cacheList = null;
public void invalidate(String... itemIds ) {
String cacheId = getCacheId(itemIds);
this.cacheMap.remove(cacheId);
if(itemIds.length>1){
String[] listId = new String[itemIds.length-1];
for( int a=0; a<itemIds.length; a++){
listId[a] = itemIds[a];
}
this.cacheList.remove(getCacheId(listId));
}
}
@Override
......@@ -59,14 +69,35 @@ abstract public class CacheImpl<T> implements Cache<T> {
}
public Map<String,String> list(String... prefixs) throws Exception{
String cacheId = "default";
if(prefixs.length>0){
cacheId = this.getCacheId(prefixs);
}
Map<String, String> list = this.cacheList.get(cacheId);
if(list==null){
if(prefixs.length>0){
list = this.getListFromStore(prefixs);
} else {
list = this.getListFromStore("");
}
this.cacheList.put(cacheId, list);
}
return new HashMap<String,String>(this.cacheList.get(cacheId));
/*
if( this.cacheList == null){
if( prefixs.length>0){
this.cacheList = this.getListFromStore(prefixs);
cacheId = this.getCacheId(prefixs);
Map<String,String> list = this.getListFromStore(prefixs);
this.cacheList.put(cacheId, list);
} else {
this.cacheList = this.getListFromStore("");
Map<String,String> list = this.getListFromStore("");
this.cacheList.put(cacheId, list);
}
}
return new HashMap<String,String>(this.cacheList);
return new HashMap<String,String>(this.cacheList.get(cacheId));
*/
}
@Override
......@@ -78,17 +109,20 @@ abstract public class CacheImpl<T> implements Cache<T> {
@Scheduled(cron = "${cache.clearschedule}")
public void clearCache() {
this.cacheMap.clear();
this.cacheList = null;
this.cacheList = new ConcurrentHashMap<String, Map<String,String>>();;
}
public String getCacheId( String... ids ){
StringBuilder id = new StringBuilder();
for (int i = 0; i < ids.length; ++i) {
id.append(ids[i]);
id.append("-");
if(!"".equals(ids[i])){
id.append(ids[i]);
id.append("-");
}
}
String returnValue = id.toString();
return returnValue.substring(0, returnValue.length()-1);
String substring = returnValue.substring(0, returnValue.length()-1);
return substring;
}
abstract protected T getFromStore(String... itemIds) throws Exception;
......
......@@ -913,7 +913,6 @@ public class CardController {
Rule rule = ruleCache.getItem(boardId,taskId);
if(rule==null){
ocm.logout();
logger.warn("Rule Not Found: " + boardId + "." + taskId);
throw new ResourceNotFoundException();
}
......@@ -1030,15 +1029,12 @@ public class CardController {
String.format(URI.TASKS_URI, boardId, phaseId, cardId,
taskId));
if (node == null) {
ocm.logout();
throw new ResourceNotFoundException();
}
node.remove();
ocm.save();