Full Code of Netflix/SimianArmy for AI

master e8eb9f3bad23 cached
289 files
1.3 MB
298.8k tokens
1950 symbols
1 requests
Download .txt
Showing preview only (1,397K chars total). Download the full file or copy to clipboard to get everything.
Repository: Netflix/SimianArmy
Branch: master
Commit: e8eb9f3bad23
Files: 289
Total size: 1.3 MB

Directory structure:
gitextract_54dtl7c9/

├── .gitignore
├── .netflixoss
├── .travis.yml
├── CHANGELOG.md
├── GNUmakefile
├── LICENSE
├── OSSMETADATA
├── README.md
├── build.gradle
├── buildViaTravis.sh
├── codequality/
│   ├── checkstyle.xml
│   └── org.eclipse.jdt.core.prefs
├── gradle/
│   └── wrapper/
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── installViaTravis.sh
├── settings.gradle
└── src/
    ├── main/
    │   ├── java/
    │   │   └── com/
    │   │       └── netflix/
    │   │           └── simianarmy/
    │   │               ├── AbstractEmailBuilder.java
    │   │               ├── CloudClient.java
    │   │               ├── EmailBuilder.java
    │   │               ├── EventType.java
    │   │               ├── FeatureNotEnabledException.java
    │   │               ├── GroupType.java
    │   │               ├── InstanceGroupNotFoundException.java
    │   │               ├── Monkey.java
    │   │               ├── MonkeyCalendar.java
    │   │               ├── MonkeyConfiguration.java
    │   │               ├── MonkeyEmailNotifier.java
    │   │               ├── MonkeyRecorder.java
    │   │               ├── MonkeyRunner.java
    │   │               ├── MonkeyScheduler.java
    │   │               ├── MonkeyType.java
    │   │               ├── NamedType.java
    │   │               ├── NotFoundException.java
    │   │               ├── Resource.java
    │   │               ├── ResourceType.java
    │   │               ├── aws/
    │   │               │   ├── AWSEmailNotifier.java
    │   │               │   ├── AWSResource.java
    │   │               │   ├── AWSResourceType.java
    │   │               │   ├── RDSRecorder.java
    │   │               │   ├── STSAssumeRoleSessionCredentialsProvider.java
    │   │               │   ├── SimpleDBRecorder.java
    │   │               │   ├── conformity/
    │   │               │   │   ├── RDSConformityClusterTracker.java
    │   │               │   │   ├── SimpleDBConformityClusterTracker.java
    │   │               │   │   ├── crawler/
    │   │               │   │   │   └── AWSClusterCrawler.java
    │   │               │   │   └── rule/
    │   │               │   │       ├── BasicConformityEurekaClient.java
    │   │               │   │       ├── ConformityEurekaClient.java
    │   │               │   │       ├── CrossZoneLoadBalancing.java
    │   │               │   │       ├── InstanceHasHealthCheckUrl.java
    │   │               │   │       ├── InstanceHasStatusUrl.java
    │   │               │   │       ├── InstanceInSecurityGroup.java
    │   │               │   │       ├── InstanceInVPC.java
    │   │               │   │       ├── InstanceIsHealthyInEureka.java
    │   │               │   │       ├── InstanceTooOld.java
    │   │               │   │       └── SameZonesInElbAndAsg.java
    │   │               │   └── janitor/
    │   │               │       ├── ASGJanitor.java
    │   │               │       ├── EBSSnapshotJanitor.java
    │   │               │       ├── EBSVolumeJanitor.java
    │   │               │       ├── ELBJanitor.java
    │   │               │       ├── ImageJanitor.java
    │   │               │       ├── InstanceJanitor.java
    │   │               │       ├── LaunchConfigJanitor.java
    │   │               │       ├── RDSJanitorResourceTracker.java
    │   │               │       ├── SimpleDBJanitorResourceTracker.java
    │   │               │       ├── VolumeTaggingMonkey.java
    │   │               │       ├── crawler/
    │   │               │       │   ├── ASGJanitorCrawler.java
    │   │               │       │   ├── AbstractAWSJanitorCrawler.java
    │   │               │       │   ├── EBSSnapshotJanitorCrawler.java
    │   │               │       │   ├── EBSVolumeJanitorCrawler.java
    │   │               │       │   ├── ELBJanitorCrawler.java
    │   │               │       │   ├── InstanceJanitorCrawler.java
    │   │               │       │   ├── LaunchConfigJanitorCrawler.java
    │   │               │       │   └── edda/
    │   │               │       │       ├── EddaASGJanitorCrawler.java
    │   │               │       │       ├── EddaEBSSnapshotJanitorCrawler.java
    │   │               │       │       ├── EddaEBSVolumeJanitorCrawler.java
    │   │               │       │       ├── EddaELBJanitorCrawler.java
    │   │               │       │       ├── EddaImageJanitorCrawler.java
    │   │               │       │       ├── EddaInstanceJanitorCrawler.java
    │   │               │       │       ├── EddaLaunchConfigJanitorCrawler.java
    │   │               │       │       └── EddaUtils.java
    │   │               │       └── rule/
    │   │               │           ├── ami/
    │   │               │           │   └── UnusedImageRule.java
    │   │               │           ├── asg/
    │   │               │           │   ├── ASGInstanceValidator.java
    │   │               │           │   ├── DiscoveryASGInstanceValidator.java
    │   │               │           │   ├── DummyASGInstanceValidator.java
    │   │               │           │   ├── OldEmptyASGRule.java
    │   │               │           │   └── SuspendedASGRule.java
    │   │               │           ├── elb/
    │   │               │           │   └── OrphanedELBRule.java
    │   │               │           ├── generic/
    │   │               │           │   ├── TagValueExclusionRule.java
    │   │               │           │   └── UntaggedRule.java
    │   │               │           ├── instance/
    │   │               │           │   └── OrphanedInstanceRule.java
    │   │               │           ├── launchconfig/
    │   │               │           │   └── OldUnusedLaunchConfigRule.java
    │   │               │           ├── snapshot/
    │   │               │           │   └── NoGeneratedAMIRule.java
    │   │               │           └── volume/
    │   │               │               ├── DeleteOnTerminationRule.java
    │   │               │               └── OldDetachedVolumeRule.java
    │   │               ├── basic/
    │   │               │   ├── BasicCalendar.java
    │   │               │   ├── BasicChaosMonkeyContext.java
    │   │               │   ├── BasicConfiguration.java
    │   │               │   ├── BasicMonkeyServer.java
    │   │               │   ├── BasicRecorderEvent.java
    │   │               │   ├── BasicScheduler.java
    │   │               │   ├── BasicSimianArmyContext.java
    │   │               │   ├── LocalDbRecorder.java
    │   │               │   ├── calendars/
    │   │               │   │   └── BavarianCalendar.java
    │   │               │   ├── chaos/
    │   │               │   │   ├── BasicChaosEmailNotifier.java
    │   │               │   │   ├── BasicChaosInstanceSelector.java
    │   │               │   │   ├── BasicChaosMonkey.java
    │   │               │   │   ├── BasicInstanceGroup.java
    │   │               │   │   └── CloudFormationChaosMonkey.java
    │   │               │   ├── conformity/
    │   │               │   │   ├── BasicConformityEmailBuilder.java
    │   │               │   │   ├── BasicConformityMonkey.java
    │   │               │   │   └── BasicConformityMonkeyContext.java
    │   │               │   └── janitor/
    │   │               │       ├── BasicJanitorEmailBuilder.java
    │   │               │       ├── BasicJanitorMonkey.java
    │   │               │       ├── BasicJanitorMonkeyContext.java
    │   │               │       ├── BasicJanitorRuleEngine.java
    │   │               │       └── BasicVolumeTaggingMonkeyContext.java
    │   │               ├── chaos/
    │   │               │   ├── BlockAllNetworkTrafficChaosType.java
    │   │               │   ├── BurnCpuChaosType.java
    │   │               │   ├── BurnIoChaosType.java
    │   │               │   ├── ChaosCrawler.java
    │   │               │   ├── ChaosEmailNotifier.java
    │   │               │   ├── ChaosInstance.java
    │   │               │   ├── ChaosInstanceSelector.java
    │   │               │   ├── ChaosMonkey.java
    │   │               │   ├── ChaosType.java
    │   │               │   ├── DetachVolumesChaosType.java
    │   │               │   ├── FailDnsChaosType.java
    │   │               │   ├── FailDynamoDbChaosType.java
    │   │               │   ├── FailEc2ChaosType.java
    │   │               │   ├── FailS3ChaosType.java
    │   │               │   ├── FillDiskChaosType.java
    │   │               │   ├── KillProcessesChaosType.java
    │   │               │   ├── NetworkCorruptionChaosType.java
    │   │               │   ├── NetworkLatencyChaosType.java
    │   │               │   ├── NetworkLossChaosType.java
    │   │               │   ├── NullRouteChaosType.java
    │   │               │   ├── ScriptChaosType.java
    │   │               │   ├── ShutdownInstanceChaosType.java
    │   │               │   └── SshConfig.java
    │   │               ├── client/
    │   │               │   ├── MonkeyRestClient.java
    │   │               │   ├── aws/
    │   │               │   │   ├── AWSClient.java
    │   │               │   │   └── chaos/
    │   │               │   │       ├── ASGChaosCrawler.java
    │   │               │   │       ├── FilteringChaosCrawler.java
    │   │               │   │       └── TagPredicate.java
    │   │               │   ├── edda/
    │   │               │   │   └── EddaClient.java
    │   │               │   └── vsphere/
    │   │               │       ├── PropertyBasedTerminationStrategy.java
    │   │               │       ├── TerminationStrategy.java
    │   │               │       ├── VSphereClient.java
    │   │               │       ├── VSphereContext.java
    │   │               │       ├── VSphereGroups.java
    │   │               │       └── VSphereServiceConnection.java
    │   │               ├── conformity/
    │   │               │   ├── AutoScalingGroup.java
    │   │               │   ├── Cluster.java
    │   │               │   ├── ClusterCrawler.java
    │   │               │   ├── Conformity.java
    │   │               │   ├── ConformityClusterTracker.java
    │   │               │   ├── ConformityEmailBuilder.java
    │   │               │   ├── ConformityEmailNotifier.java
    │   │               │   ├── ConformityMonkey.java
    │   │               │   ├── ConformityRule.java
    │   │               │   └── ConformityRuleEngine.java
    │   │               ├── janitor/
    │   │               │   ├── AbstractJanitor.java
    │   │               │   ├── DryRunnableJanitor.java
    │   │               │   ├── DryRunnableJanitorException.java
    │   │               │   ├── Janitor.java
    │   │               │   ├── JanitorCrawler.java
    │   │               │   ├── JanitorEmailBuilder.java
    │   │               │   ├── JanitorEmailNotifier.java
    │   │               │   ├── JanitorMonkey.java
    │   │               │   ├── JanitorResourceTracker.java
    │   │               │   ├── JanitorRuleEngine.java
    │   │               │   └── Rule.java
    │   │               ├── resources/
    │   │               │   ├── chaos/
    │   │               │   │   └── ChaosMonkeyResource.java
    │   │               │   └── janitor/
    │   │               │       └── JanitorMonkeyResource.java
    │   │               └── tunable/
    │   │                   ├── TunableInstanceGroup.java
    │   │                   └── TunablyAggressiveChaosMonkey.java
    │   ├── resources/
    │   │   ├── chaos.properties
    │   │   ├── client.properties
    │   │   ├── conformity.properties
    │   │   ├── janitor.properties
    │   │   ├── log4j.properties
    │   │   ├── scripts/
    │   │   │   ├── burncpu.sh
    │   │   │   ├── burnio.sh
    │   │   │   ├── faildns.sh
    │   │   │   ├── faildynamodb.sh
    │   │   │   ├── failec2.sh
    │   │   │   ├── fails3.sh
    │   │   │   ├── filldisk.sh
    │   │   │   ├── killprocesses.sh
    │   │   │   ├── networkcorruption.sh
    │   │   │   ├── networklatency.sh
    │   │   │   ├── networkloss.sh
    │   │   │   └── nullroute.sh
    │   │   ├── simianarmy.properties
    │   │   └── volumeTagging.properties
    │   └── webapp/
    │       └── WEB-INF/
    │           └── web.xml
    └── test/
        ├── java/
        │   └── com/
        │       └── netflix/
        │           └── simianarmy/
        │               ├── TestMonkey.java
        │               ├── TestMonkeyContext.java
        │               ├── TestMonkeyRunner.java
        │               ├── TestUtils.java
        │               ├── aws/
        │               │   ├── TestAWSEmailNotifier.java
        │               │   ├── TestRDSRecorder.java
        │               │   ├── TestSimpleDBRecorder.java
        │               │   ├── conformity/
        │               │   │   ├── TestASGOwnerEmailTag.java
        │               │   │   ├── TestRDSConformityClusterTracker.java
        │               │   │   └── rule/
        │               │   │       └── TestInstanceInVPC.java
        │               │   └── janitor/
        │               │       ├── TestAWSResource.java
        │               │       ├── TestRDSJanitorResourceTracker.java
        │               │       ├── TestSimpleDBJanitorResourceTracker.java
        │               │       ├── crawler/
        │               │       │   ├── TestASGJanitorCrawler.java
        │               │       │   ├── TestEBSSnapshotJanitorCrawler.java
        │               │       │   ├── TestEBSVolumeJanitorCrawler.java
        │               │       │   ├── TestELBJanitorCrawler.java
        │               │       │   ├── TestInstanceJanitorCrawler.java
        │               │       │   └── TestLaunchConfigJanitorCrawler.java
        │               │       └── rule/
        │               │           ├── TestMonkeyCalendar.java
        │               │           ├── asg/
        │               │           │   ├── TestOldEmptyASGRule.java
        │               │           │   └── TestSuspendedASGRule.java
        │               │           ├── elb/
        │               │           │   └── TestOrphanedELBRule.java
        │               │           ├── generic/
        │               │           │   ├── TestTagValueExclusionRule.java
        │               │           │   └── TestUntaggedRule.java
        │               │           ├── instance/
        │               │           │   └── TestOrphanedInstanceRule.java
        │               │           ├── launchconfig/
        │               │           │   └── TestOldUnusedLaunchConfigRule.java
        │               │           ├── snapshot/
        │               │           │   └── TestNoGeneratedAMIRule.java
        │               │           └── volume/
        │               │               └── TestOldDetachedVolumeRule.java
        │               ├── basic/
        │               │   ├── TestBasicCalendar.java
        │               │   ├── TestBasicConfiguration.java
        │               │   ├── TestBasicContext.java
        │               │   ├── TestBasicMonkeyServer.java
        │               │   ├── TestBasicRecorderEvent.java
        │               │   ├── TestBasicScheduler.java
        │               │   ├── calendar/
        │               │   │   └── TestBavarianCalendar.java
        │               │   ├── chaos/
        │               │   │   ├── TestBasicChaosEmailNotifier.java
        │               │   │   ├── TestBasicChaosInstanceSelector.java
        │               │   │   ├── TestBasicChaosMonkey.java
        │               │   │   └── TestCloudFormationChaosMonkey.java
        │               │   └── janitor/
        │               │       └── TestBasicJanitorRuleEngine.java
        │               ├── chaos/
        │               │   ├── TestChaosMonkeyArmy.java
        │               │   └── TestChaosMonkeyContext.java
        │               ├── client/
        │               │   ├── aws/
        │               │   │   ├── TestAWSClient.java
        │               │   │   └── chaos/
        │               │   │       ├── TestASGChaosCrawler.java
        │               │   │       └── TestFilterASGChaosCrawler.java
        │               │   └── vsphere/
        │               │       ├── TestPropertyBasedTerminationStrategy.java
        │               │       ├── TestVSpehereClient.java
        │               │       ├── TestVSphereContext.java
        │               │       ├── TestVSphereGroups.java
        │               │       └── TestVSphereServiceConnection.java
        │               ├── conformity/
        │               │   ├── TestCrossZoneLoadBalancing.java
        │               │   └── TestSameZonesInElbAndAsg.java
        │               ├── janitor/
        │               │   ├── TestAbstractJanitor.java
        │               │   └── TestBasicJanitorMonkeyContext.java
        │               ├── resources/
        │               │   └── chaos/
        │               │       └── TestChaosMonkeyResource.java
        │               └── tunable/
        │                   └── TestTunablyAggressiveChaosMonkey.java
        └── resources/
            ├── chaos.properties
            ├── client.properties
            ├── com/
            │   └── netflix/
            │       └── simianarmy/
            │           ├── chaos/
            │           │   ├── all.properties
            │           │   ├── cloudformation.properties
            │           │   ├── disabled.properties
            │           │   ├── enabledA.properties
            │           │   ├── enabledAwith0.properties
            │           │   ├── enabledAwithout1.properties
            │           │   ├── enabledB.properties
            │           │   ├── fullProbability.properties
            │           │   ├── globalNotificationEnabled.properties
            │           │   ├── mandatoryTerminationDisabled.properties
            │           │   ├── mandatoryTerminationInsideWindow.properties
            │           │   ├── mandatoryTerminationNoOptInTime.properties
            │           │   ├── mandatoryTerminationNotDefined.properties
            │           │   ├── mandatoryTerminationOutsideWindow.properties
            │           │   ├── noProbability.properties
            │           │   ├── noProbabilityByName.properties
            │           │   ├── notificationEnabled.properties
            │           │   ├── ondemandTermination.properties
            │           │   ├── ondemandTerminationDisabled.properties
            │           │   ├── propertiesWithDefaults.properties
            │           │   ├── terminationPerDayAsBiggerThanOne.properties
            │           │   ├── terminationPerDayAsNegative.properties
            │           │   ├── terminationPerDayAsOne.properties
            │           │   ├── terminationPerDayAsSmallerThanOne.properties
            │           │   ├── terminationPerDayAsVerySmall.properties
            │           │   ├── terminationPerDayAsZero.properties
            │           │   ├── terminationPerDayGroupLevel.properties
            │           │   ├── unleashedEnabledA.properties
            │           │   └── unleashedEnabledB.properties
            │           └── resources/
            │               └── chaos/
            │                   └── getChaosEventsResponse.json
            ├── log4j.properties
            ├── proxy.properties
            └── simianarmy.properties

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log

# OS generated files #
######################
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db

# Editor Files #
################
*~
*.swp

# Gradle Files #
################
.gradle

# Build output directies
/target
*/target
/build
*/build
/bin
*/bin
/test-output
*/test-output

# IntelliJ specific files/directories
out
.idea
*.ipr
*.iws
*.iml
atlassian-ide-plugin.xml

# Eclipse specific files/directories
.classpath
.project
.settings
.metadata

# NetBeans specific files/directories
.nbattrs
/bin
/test-output


================================================
FILE: .netflixoss
================================================
cloudbees_disabled=true


================================================
FILE: .travis.yml
================================================
language: java
jdk:
- oraclejdk8
sudo: required
dist: trusty
install: ./installViaTravis.sh
script: ./buildViaTravis.sh
cache:
  directories:
  - $HOME/.gradle/caches
env:
  global:
  - secure: WCRqvIKdPdIsoDhsJWZNBZhEH7Jdgz2fmkjzozVjs4dq36ySrH71udNtZcPIsTwjmHpRaGX0XCgmwLC5WorS2TBJJ87oghCP3WWQGMBLcCdXHS8quRdAHLHpNfao/BQrBEA/gmCYoJZdmXKFDc+XKXS5NBrHkkvVfLGCumcP0AI=
  - secure: TKnGiZyCtWWI/ei2lNDvGIjyAI4W8xMNOlXT6tGiWJgexvFQpTl2NgkMqgwbxReyxj37vdUnn9Lb/883G6zL/uB+l5aCjeCG//6GAbJYdrSZQCE/UCo7iMlAxyqfuIlKcJABIhwpP8Fg4RwqxJG19Tbx5ddg8RP8yKAi1QNx06Y=
  - secure: nUn8s+1fV60Hxb9V9DouFIOGHeBpeTD7l6Yadw4gthvi/tZndZ+L/Crh1Z9pAU69NqEHG/VcFLUMNER7dQ4rugVbcbfQueeCdnVpmStLS97tAl8kArhpWCk8dQi47IANuQw7U0nVlg3pA8w9HLZX6ee9PnhyG1oOnluPC/x2Or4=
  - secure: KTtxnPJWfkwNwYkd2IxKAc4dUc6jF0Fd6uhrqK5q36z0RnY4b/gKlx8bjGPcZA5hutNmiN/gxyvpbL/bvVg9buQ2vkybaPZpzpLwhHTXiD5accjQUMuwF8DFYpzIb104hkgzHbrW18JRImK539ib5TTanF3I08F04LssSXG8NnY=


================================================
FILE: CHANGELOG.md
================================================


================================================
FILE: GNUmakefile
================================================
reformat:
	eclipse -nosplash -application org.eclipse.jdt.core.JavaCodeFormatter -verbose -config $(shell pwd)/codequality/org.eclipse.jdt.core.prefs $(shell pwd)/src
	find $(shell pwd)/src -name \*.java | xargs perl -pi -e 's/{ /{/g; s/(\S) }/$$1}/g; s/\* $$/\*/; s/([.]<[^>]+>)\s+/$$1/g'


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2012 Netflix, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: OSSMETADATA
================================================
osslifecycle=archived


================================================
FILE: README.md
================================================
[![NetflixOSS Lifecycle](https://img.shields.io/osslifecycle/Netflix/SimianArmy.svg)](OSSMETADATA)
[![Build Status](https://travis-ci.org/Netflix/SimianArmy.svg?branch=master)](https://travis-ci.org/Netflix/SimianArmy)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

## PROJECT STATUS: RETIRED

**The Simian Army project is no longer actively maintained**. Some of the Simian
Army functionality has been moved to other Netflix projects:

* A [newer version of Chaos Monkey](https://github.com/netflix/chaosmonkey) is available as a standalone service.
* [Swabbie] is a new standalone service that will replace the functionality provided by Janitor Monkey.
* Conformity Monkey functionality will be rolled into other [Spinnaker] backend services.


[Swabbie]: https://github.com/spinnaker/swabbie
[Spinnaker]: https://www.spinnaker.io/

### DESCRIPTION

The Simian Army is a suite of tools for keeping your cloud operating in top
form.  Chaos Monkey, the first member, is a resiliency tool that helps ensure
that your applications can tolerate random instance failures


### DETAILS

Please see the [wiki](https://github.com/Netflix/SimianArmy/wiki).

### SUPPORT

[Simian Army Google group](http://groups.google.com/group/simianarmy-users)

Because the project is no longer maintained, there is a good chance that nobody will be able to answer a support question.

### LICENSE

Copyright 2012-2016 Netflix, Inc.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in
compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is
distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions and limitations under the
License.


================================================
FILE: build.gradle
================================================
buildscript {
    repositories {
        jcenter()
    }
}

plugins {
    id 'nebula.netflixoss' version '3.2.3'
    id 'net.saliman.cobertura' version '2.2.7'
    id 'com.github.hierynomus.license' version '0.11.0'
}

// Establish version and status
ext.githubProjectName = 'SimianArmy'
group = "com.netflix.${project.name}"
apply plugin:'eclipse-wtp'

repositories {
    mavenLocal()
    mavenCentral()
}

apply plugin: 'war'
apply plugin: 'jetty'

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    // for the VMWareClient
    compile 'com.cloudbees.thirdparty:vijava:5.0.0'

    // for DB support outside of AWS (SimpleDB not available)
    compile 'org.mapdb:mapdb:0.9.5'

    compile 'com.sun.jersey:jersey-servlet:1.19'
    compile 'org.slf4j:slf4j-api:1.7.2'
    compile 'org.codehaus.jackson:jackson-core-asl:1.9.2'
    compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.2'
    compile 'com.netflix.eureka:eureka-client:1.4.1'
    compile 'com.amazonaws:aws-java-sdk:1.11.28'
    compile 'commons-lang:commons-lang:2.6'
    compile 'com.google.guava:guava:11.0.2'
    compile 'org.apache.httpcomponents:httpclient:4.3'
    compile 'com.google.auto.service:auto-service:1.0-rc2'
    compile 'org.apache.jclouds.driver:jclouds-jsch:1.9.0'
    compile 'org.apache.jclouds.driver:jclouds-slf4j:1.9.0'
    compile 'org.apache.jclouds.api:ec2:1.9.0'
    compile 'org.apache.jclouds.provider:aws-ec2:1.9.0'
    compile 'com.netflix.servo:servo-core:0.12.11'
    compile 'org.springframework:spring-jdbc:4.2.5.RELEASE'
    compile 'com.zaxxer:HikariCP:2.4.7'

    testCompile 'org.testng:testng:6.3.1'
    testCompile 'org.mockito:mockito-core:1.8.5'

    runtime 'org.slf4j:slf4j-log4j12:1.6.1'

    providedCompile 'javax.servlet:servlet-api:2.5'
}

test {
    useTestNG()
}

tasks.withType(JavaCompile) {
    options.compilerArgs << "-Xlint"
}

license {
    exclude '**/*.properties'
    exclude '**/*.json'
    exclude '**/*.sh'
}

task coreJar(type: Jar) {
    from sourceSets.main.output
    include '**'
}

publishing {
    publications {
        mavenWar(MavenPublication) {
            from components.web
            artifact coreJar { classifier "core" }
        }
    }
}

artifactoryPublish {
    publications('mavenWar')
}


================================================
FILE: buildViaTravis.sh
================================================
#!/bin/bash
# This script will build the project.

if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
  echo -e "Build Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]"
  ./gradlew clean build
elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then
  echo -e 'Build Branch with Snapshot => Branch ['$TRAVIS_BRANCH']'
  ./gradlew -Prelease.travisci=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build snapshot 
elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
  echo -e 'Build Branch for Release => Branch ['$TRAVIS_BRANCH']  Tag ['$TRAVIS_TAG']'
  case "$TRAVIS_TAG" in
  *-rc\.*)
    ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" candidate
    ;;
  *)
    ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" final
    ;;
  esac
else
  echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH']  Tag ['$TRAVIS_TAG']  Pull Request ['$TRAVIS_PULL_REQUEST']'
  ./gradlew build
fi


================================================
FILE: codequality/checkstyle.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">

<module name="Checker">

    <!-- Checks that a package-info.java file exists for each package.     -->
    <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
    <!--
    <module name="JavadocPackage">
      <property name="allowLegacy" value="true"/>
    </module>
    -->

    <!-- Checks whether files end with a new line.                        -->
    <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
    <!--module name="NewlineAtEndOfFile"/-->

    <!-- Checks that property files contain the same keys.         -->
    <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
    <module name="Translation"/>

    <!-- Checks for Size Violations.                    -->
    <!-- See http://checkstyle.sf.net/config_sizes.html -->
    <module name="FileLength"/>

    <!-- Checks for whitespace                               -->
    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
    <module name="FileTabCharacter"/>

    <!-- Miscellaneous other checks.                   -->
    <!-- See http://checkstyle.sf.net/config_misc.html -->
    <module name="RegexpSingleline">
       <property name="format" value="\s+$"/>
       <property name="minimum" value="0"/>
       <property name="maximum" value="0"/>
       <property name="message" value="Line has trailing spaces."/>
       <property name="severity" value="info"/>
    </module>

    <module name="TreeWalker">

        <!-- Checks for Javadoc comments.                     -->
        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
        <module name="JavadocMethod">
          <property name="scope" value="package"/>
          <property name="allowMissingParamTags" value="true"/>
          <property name="allowMissingThrowsTags" value="true"/>
          <property name="allowMissingReturnTag" value="true"/>
          <property name="allowThrowsTagsForSubclasses" value="true"/>
          <property name="allowUndeclaredRTE" value="true"/>
          <property name="allowMissingPropertyJavadoc" value="true"/>
        </module>
        <module name="JavadocType">
          <property name="scope" value="package"/>
        </module>
        <module name="JavadocVariable">
          <property name="scope" value="package"/>
        </module>
        <module name="JavadocStyle">
          <property name="checkEmptyJavadoc" value="true"/>
        </module>

        <!-- Checks for Naming Conventions.                  -->
        <!-- See http://checkstyle.sf.net/config_naming.html -->
        <module name="ConstantName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <module name="StaticVariableName"/>
        <module name="TypeName"/>

        <!-- Checks for imports                              -->
        <!-- See http://checkstyle.sf.net/config_import.html -->
        <module name="AvoidStarImport"/>
        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>


        <!-- Checks for Size Violations.                    -->
        <!-- See http://checkstyle.sf.net/config_sizes.html -->
        <module name="LineLength">
          <!-- what is a good max value? -->
          <property name="max" value="120"/>
          <!-- ignore lines like "$File: //depot/... $" -->
          <property name="ignorePattern" value="\$File.*\$"/>
          <property name="severity" value="info"/>
        </module>
        <module name="MethodLength"/>
        <module name="ParameterNumber"/>


        <!-- Checks for whitespace                               -->
        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
        <module name="EmptyForIteratorPad"/>
        <module name="GenericWhitespace"/>
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter"/>
        <module name="NoWhitespaceBefore"/>
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround"/>

        <!-- Modifier Checks                                    -->
        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
        <module name="ModifierOrder"/>
        <module name="RedundantModifier"/>


        <!-- Checks for blocks. You know, those {}'s         -->
        <!-- See http://checkstyle.sf.net/config_blocks.html -->
        <module name="AvoidNestedBlocks"/>
        <module name="EmptyBlock">
          <property name="option" value="text"/>
        </module>
        <module name="LeftCurly"/>
        <module name="NeedBraces"/>
        <module name="RightCurly"/>


        <!-- Checks for common coding problems               -->
        <!-- See http://checkstyle.sf.net/config_coding.html -->
        <!-- <module name="AvoidInlineConditionals"/> -->
        <module name="EmptyStatement"/>
        <module name="EqualsHashCode"/>
        <module name="HiddenField">
          <property name="ignoreConstructorParameter" value="true"/>
          <property name="ignoreSetter" value="true"/>
          <property name="severity" value="warning"/>
        </module>
        <module name="IllegalInstantiation"/>
        <module name="InnerAssignment"/>
        <module name="MagicNumber">
          <property name="severity" value="warning"/>
        </module>
        <module name="MissingSwitchDefault"/>
        <!-- Problem with finding exception types... -->
        <module name="RedundantThrows">
          <property name="allowUnchecked" value="true"/>
          <property name="suppressLoadErrors" value="true"/>
          <property name="severity" value="info"/>
        </module>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>

        <!-- Checks for class design                         -->
        <!-- See http://checkstyle.sf.net/config_design.html -->
        <!-- <module name="DesignForExtension"/> -->
        <module name="FinalClass"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="InterfaceIsType"/>
        <module name="VisibilityModifier"/>


        <!-- Miscellaneous other checks.                   -->
        <!-- See http://checkstyle.sf.net/config_misc.html -->
        <module name="ArrayTypeStyle"/>
        <!-- <module name="FinalParameters"/> -->
        <module name="TodoComment">
          <property name="format" value="TODO"/>
          <property name="severity" value="info"/>
        </module>
        <module name="UpperEll"/>

        <module name="FileContentsHolder"/> <!-- Required by comment suppression filters -->

    </module>

    <!-- Enable suppression comments -->
    <module name="SuppressionCommentFilter">
      <property name="offCommentFormat" value="CHECKSTYLE IGNORE\s+(\S+)"/>
      <property name="onCommentFormat" value="CHECKSTYLE END IGNORE\s+(\S+)"/>
      <property name="checkFormat" value="$1"/>
    </module>
    <module name="SuppressWithNearbyCommentFilter">
      <!-- Syntax is "SUPPRESS CHECKSTYLE name" -->
      <property name="commentFormat" value="SUPPRESS CHECKSTYLE (\w+)"/>
      <property name="checkFormat" value="$1"/>
      <property name="influenceFormat" value="1"/>
    </module>
</module>


================================================
FILE: codequality/org.eclipse.jdt.core.prefs
================================================
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=120
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=120
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Feb 22 15:12:15 PST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip


================================================
FILE: gradle.properties
================================================


================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: installViaTravis.sh
================================================
#!/bin/bash
# This script will build the project.

if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
  echo -e "Assemble Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]"
  ./gradlew clean assemble --stacktrace
elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then
  echo -e 'Assemble Branch with Snapshot => Branch ['$TRAVIS_BRANCH']'
  ./gradlew -Prelease.travisci=true assemble 
elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
  echo -e 'Assemble Branch for Release => Branch ['$TRAVIS_BRANCH']  Tag ['$TRAVIS_TAG']'
  ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true assemble
else
  echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH']  Tag ['$TRAVIS_TAG']  Pull Request ['$TRAVIS_PULL_REQUEST']'
  ./gradlew assemble
fi


================================================
FILE: settings.gradle
================================================
rootProject.name='simianarmy'


================================================
FILE: src/main/java/com/netflix/simianarmy/AbstractEmailBuilder.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/** The abstract email builder. */
public abstract class AbstractEmailBuilder implements EmailBuilder {

    @Override
    public String buildEmailBody(String emailAddress) {
        StringBuilder body = new StringBuilder();
        String header = getHeader();
        if (header != null) {
            body.append(header);
        }
        String entryTable = getEntryTable(emailAddress);
        if (entryTable != null) {
            body.append(entryTable);
        }
        String footer = getFooter();
        if (footer != null) {
            body.append(footer);
        }
        return body.toString();
    }

    /**
     * Gets the header to the email body.
     */
    protected abstract String getHeader();

    /**
     * Gets the table of entries in the email body.
     * @param emailAddress the email address to notify
     * @return the HTML string representing the table for the resources to send to the
     * email address
     */
    protected abstract String getEntryTable(String emailAddress);

    /**
     * Gets the footer of the email body.
     */
    protected abstract String getFooter();

    /**
     * Gets the HTML cell in the table of a string value.
     * @param value the string to put in the table
     * @return the HTML text
     */
    protected String getHtmlCell(String value) {
        return "<td style=\"padding: 4px\">" + value + "</td>";
    }

    /**
     * Gets the HTML string displaying the table header with the specified column names.
     * @param columns the column names for the table
     */
    protected String getHtmlTableHeader(String[] columns) {
        StringBuilder tableHeader = new StringBuilder();
        tableHeader.append(
                "<table border=\"1\" style=\"border-width:1px; border-spacing: 0px; border-collapse: seperate;\">");
        tableHeader.append("<tr style=\"background-color: #E8E8E8;\" >");
        for (String col : columns) {
            tableHeader.append(getHtmlCell(col));
        }
        tableHeader.append("</tr>");
        return tableHeader.toString();
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/CloudClient.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import org.jclouds.compute.ComputeService;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ssh.SshClient;

import java.util.List;
import java.util.Map;

/**
 * The CloudClient interface. This abstractions provides the interface that the monkeys need to interact with
 * "the cloud".
 */
public interface CloudClient {

    /**
     * Terminates instance.
     *
     * @param instanceId
     *            the instance id
     *
     * @throws NotFoundException
     *             if the instance no longer exists or was already terminated after the crawler discovered it then you
     *             should get a NotFoundException
     */
    void terminateInstance(String instanceId);

    /**
     * Deletes an auto scaling group.
     *
     * @param asgName
     *          the auto scaling group name
     */
    void deleteAutoScalingGroup(String asgName);

    /**
     * Deletes a launch configuration.
     *
     * @param launchConfigName
     *          the launch configuration name
     */
    void deleteLaunchConfiguration(String launchConfigName);

    /**
     * Deletes a volume.
     *
     * @param volumeId
     *          the volume id
     */
    void deleteVolume(String volumeId);

    /**
     * Deletes a snapshot.
     *
     * @param snapshotId
     *          the snapshot id.
     */
    void deleteSnapshot(String snapshotId);

    /** Deletes an image.
     *
     * @param imageId
     *          the image id.
     */
     void deleteImage(String imageId);

    /**
     * Deletes an elastic load balancer.
     *
     * @param elbId
     *          the elastic load balancer id
     */
    void deleteElasticLoadBalancer(String elbId);

    /**
     * Deletes a DNS record.
     *
     * @param dnsName
     *          the DNS record to delete
     * @param dnsType
     *          the DNS type (CNAME, A, or AAAA)
     * @param hostedZoneID
     *          the ID of the hosted zone (required for AWS Route53 records)
     */
    public void deleteDNSRecord(String dnsName, String dnsType, String hostedZoneID);

     /**
     * Adds or overwrites tags for the specified resources.
     *
     * @param keyValueMap
     *          the new tags in the form of map from key to value
     *
     * @param resourceIds
     *          the list of resource ids
     */
    void createTagsForResources(Map<String, String> keyValueMap, String... resourceIds);

    /**
     * Lists all EBS volumes attached to the specified instance.
     *
     * @param instanceId
     *            the instance id
     * @param includeRoot
     *            if the root volume is on EBS, should we include it?
     *
     * @throws NotFoundException
     *             if the instance no longer exists or was already terminated after the crawler discovered it then you
     *             should get a NotFoundException
     */
    List<String> listAttachedVolumes(String instanceId, boolean includeRoot);

    /**
     * Detaches an EBS volumes from the specified instance.
     *
     * @param instanceId
     *            the instance id
     * @param volumeId
     *            the volume id
     * @param force
     *            if we should force-detach the volume.  Probably best not to use on high-value volumes.
     *
     * @throws NotFoundException
     *             if the instance no longer exists or was already terminated after the crawler discovered it then you
     *             should get a NotFoundException
     */
    void detachVolume(String instanceId, String volumeId, boolean force);

    /**
     * Returns the jClouds compute service.
     */
    ComputeService getJcloudsComputeService();

    /**
     * Returns the jClouds node id for an instance id on this CloudClient.
     */
    String getJcloudsId(String instanceId);

    /**
     * Opens an SSH connection to an instance.
     *
     * @param instanceId
     *            instance id to connect to
     * @param credentials
     *            SSH credentials to use
     * @return {@link SshClient}, in connected state
     */
    SshClient connectSsh(String instanceId, LoginCredentials credentials);

    /**
     * Finds a security group with the given name, that can be applied to the given instance.
     *
     * For example, if it is a VPC instance, it makes sure that it is in the same VPC group.
     *
     * @param instanceId
     *            the instance that the group must be applied to
     * @param groupName
     *            the name of the group to find
     *
     * @return The group id, or null if not found
     */
    String findSecurityGroup(String instanceId, String groupName);

    /**
     * Creates an (empty) security group, that can be applied to the given instance.
     *
     * @param instanceId
     *            instance that group should be applicable to
     * @param groupName
     *            name for new group
     * @param description
     *            description for new group
     *
     * @return the id of the security group
     */
    String createSecurityGroup(String instanceId, String groupName, String description);

    /**
     * Checks if we can change the security groups of an instance.
     *
     * @param instanceId
     *            instance to check
     *
     * @return true iff we can change security groups.
     */
    boolean canChangeInstanceSecurityGroups(String instanceId);

    /**
     * Sets the security groups for an instance.
     *
     * Note this is only valid for VPC instances.
     *
     * @param instanceId
     *            the instance id
     * @param groupIds
     *            ids of desired new groups
     *
     * @throws NotFoundException
     *             if the instance no longer exists or was already terminated after the crawler discovered it then you
     *             should get a NotFoundException
     */
    void setInstanceSecurityGroups(String instanceId, List<String> groupIds);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/EmailBuilder.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/** Interface for build the email body. */
public interface EmailBuilder {
    /**
     * Builds an email body for an email address.
     * @param emailAddress the email address to send notification to
     * @return the email body
     */
    String buildEmailBody(String emailAddress);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/EventType.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * Marker interface for all event type enumerations.
 */
public interface EventType extends NamedType {

}


================================================
FILE: src/main/java/com/netflix/simianarmy/FeatureNotEnabledException.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy;

/**
 * The Class FeatureNotEnabledException.
 *
 * These exceptions will be thrown when a feature is not enabled when being accessed.
 */
public class FeatureNotEnabledException extends Exception {

    private static final long serialVersionUID = 8392434473284901306L;

    /**
     * Instantiates a FeatureNotEnabledException with a message.
     * @param msg the error message
     */
    public FeatureNotEnabledException(String msg) {
        super(msg);
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/GroupType.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * Marker interface for all group type enumerations.
 */
public interface GroupType extends NamedType {

}


================================================
FILE: src/main/java/com/netflix/simianarmy/InstanceGroupNotFoundException.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy;

/**
 * The Class InstanceGroupNotFoundException.
 *
 * These exceptions will be thrown when an instance group cannot be found with the
 * given name and type.
 */
public class InstanceGroupNotFoundException extends Exception {

    private static final long serialVersionUID = -5492120875166280476L;

    private final String groupType;
    private final String groupName;

    /**
     * Instantiates an InstanceGroupNotFoundException with the group type and name.
     * @param groupType the group type
     * @param groupName the gruop name
     */
    public InstanceGroupNotFoundException(String groupType, String groupName) {
        super(errorMessage(groupType, groupName));
        this.groupType = groupType;
        this.groupName = groupName;
    }

    @Override
    public String toString() {
        return errorMessage(groupType, groupName);
    }

    private static String errorMessage(String groupType, String groupName) {
        return String.format("Instance group named '%s' [type %s] cannot be found.",
                groupName, groupType);
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/Monkey.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.simianarmy.MonkeyRecorder.Event;

/**
 * The abstract Monkey class, it provides a minimal interface from which all monkeys must be derived.
 */
public abstract class Monkey {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(Monkey.class);

    /**
     * The Interface Context.
     */
    public interface Context {

        /**
         * Scheduler.
         *
         * @return the monkey scheduler
         */
        MonkeyScheduler scheduler();

        /**
         * Calendar.
         *
         * @return the monkey calendar
         */
        MonkeyCalendar calendar();

        /**
         * Cloud client.
         *
         * @return the cloud client
         */
        CloudClient cloudClient();

        /**
         * Recorder.
         *
         * @return the monkey recorder
         */
        MonkeyRecorder recorder();

        /**
         * Add a event to the summary report. The ChaosMonkey uses this to print a summary after the chaos run is
         * complete.
         *
         * @param evt
         *            The Event to be reported
         */
        void reportEvent(Event evt);

        /**
         * Used to clear the event summary on the start of a chaos run.
         */
        void resetEventReport();

        /**
         * Returns a summary of what the chaos run did.
         */
        String getEventReport();

        /**
         * Configuration.
         *
         * @return the monkey configuration
         */
        MonkeyConfiguration configuration();
    }

    /** The context. */
    private final Context ctx;

    /**
     * Instantiates a new monkey.
     *
     * @param ctx
     *            the context
     */
    public Monkey(Context ctx) {
        this.ctx = ctx;
    }

    /**
     * Type.
     *
     * @return the monkey type enum
     */
    public abstract MonkeyType type();

    /**
     * Do monkey business.
     */
    public abstract void doMonkeyBusiness();

    /**
     * Context.
     *
     * @return the context
     */
    public Context context() {
        return ctx;
    }

    /**
     * Run. This is run on the schedule set by the MonkeyScheduler
     */
    public void run() {
        if (ctx.calendar().isMonkeyTime(this)) {
            LOGGER.info(this.type().name() + " Monkey Running ...");
            try {
                this.doMonkeyBusiness();
            } finally {
                String eventReport = context().getEventReport();
                if (eventReport != null) {
                    LOGGER.info("Reporting what I did...\n" + eventReport);
                }
            }
        } else {
            LOGGER.info("Not Time for " + this.type().name() + " Monkey");
        }
    }

    /**
     * Start. Sets up the schedule for the monkey to run on.
     */
    public void start() {
        final Monkey me = this;
        ctx.scheduler().start(this, new Runnable() {
            @Override
            public void run() {
                try {
                    me.run();
                } catch (Exception e) {
                    LOGGER.error(me.type().name() + " Monkey Error: ", e);
                }
            }
        });
    }

    /**
     * Stop. Removes the monkey from the schedule.
     */
    public void stop() {
        ctx.scheduler().stop(this);
    }

}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyCalendar.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import java.util.Calendar;
import java.util.Date;

/**
 * The Interface MonkeyCalendar used to tell if a monkey should be running or now. We only want monkeys to run during
 * business hours, so that engineers will be on-hand if something goes wrong.
 */
public interface MonkeyCalendar {

    /**
     * Checks if is monkey time.
     *
     * @param monkey
     *            the monkey
     * @return true, if is monkey time
     */
    boolean isMonkeyTime(Monkey monkey);

    /**
     * Open hour. This is the "open" hour for then the monkey should start working.
     *
     * @return the int
     */
    int openHour();

    /**
     * Close hour. This is the "close" hour for when the monkey should stop working.
     *
     * @return the int
     */
    int closeHour();

    /**
     * Get the current time using whatever timezone is used for monkey date calculations.
     *
     * @return the calendar
     */
    Calendar now();

    /** Gets the next business day from the start date after n business days.
     *
     * @param date the start date
     * @param n the number of business days from now
     * @return the business day after n business days
     */
    Date getBusinessDay(Date date, int n);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyConfiguration.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * The Interface MonkeyConfiguration.
 */
public interface MonkeyConfiguration {

    /**
     * Gets the boolean associated with property string. If not found it will return false.
     *
     * @param property
     *            the property name
     * @return the boolean value
     */
    boolean getBool(String property);

    /**
     * Gets the boolean associated with property string. If not found it will return dflt.
     *
     * @param property
     *            the property name
     * @param dflt
     *            the default value
     * @return the bool property value, or dflt if none set
     */
    boolean getBoolOrElse(String property, boolean dflt);

    /**
     * Gets the number (double) associated with property string. If not found it will return dflt.
     *
     * @param property
     *            the property name
     * @param dflt
     *            the default value
     * @return the numeric property value, or dflt if none set
     */
    double getNumOrElse(String property, double dflt);

    /**
     * Gets the string associated with property string. If not found it will return null.
     *
     * @param property
     *            the property name
     * @return the string property value
     */
    String getStr(String property);

    /**
     * Gets the string associated with property string. If not found it will return dflt.
     *
     * @param property
     *            the property name
     * @param dflt
     *            the default value
     * @return the string property value, or dflt if none set
     */
    String getStrOrElse(String property, String dflt);

    /**
     * If the configuration has dynamic elements then they should be reloaded with this.
     */
    void reload();

    /**
     * Reloads the properties of specific group.
     * @param groupName
     *          the instance group's name
     */
    void reload(String groupName);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyEmailNotifier.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;


/** The interface for the email notifier used by monkeys. */
public interface MonkeyEmailNotifier {

    /**
     * Determines if a email address is valid.
     * @param email the email
     * @return true if the email address is valid, false otherwise.
     */
    boolean isValidEmail(String email);

    /**
     * Builds an email subject for an email address.
     * @param to the destination email address
     * @return the email subject
     */
    String buildEmailSubject(String to);

    /**
     * Gets the cc email addresses for a to address.
     * @param to the to address
     * @return the cc email addresses
     */
    String[] getCcAddresses(String to);

    /**
     * Gets the source email addresses for a to address.
     * @param to the to address
     * @return the source email addresses
     */
    String getSourceAddress(String to);

    /**
     * Sends an email.
     * @param to the address sent to
     * @param subject the email subject
     * @param body the email body
     */
    void sendEmail(String to, String subject, String body);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyRecorder.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * The Interface MonkeyRecorder. This is use to store and find events in some datastore.
 */
public interface MonkeyRecorder {

    /**
     * The Interface Event.
     */
    public interface Event {

        /**
         * Event Id.
         *
         * @return the string
         */
        String id();

        /**
         * Event time.
         *
         * @return the date
         */
        Date eventTime();

        /**
         * Monkey type.
         *
         * @return the monkey type enum
         */
        MonkeyType monkeyType();

        /**
         * Event type.
         *
         * @return the event type enum
         */
        EventType eventType();

        /**
         * Region.
         *
         * @return the region for the event
         */
        String region();

        /**
         * Fields.
         *
         *
         * @return the map of strings that may have been provided when the event was created
         */
        Map<String, String> fields();

        /**
         * Field.
         *
         * @param name
         *            the name
         * @return the string associated with that field
         */
        String field(String name);

        /**
         * Adds the field.
         *
         * @param name
         *            the name
         * @param value
         *            the value
         * @return <b>this</b> so you can chain multiple addField calls together
         */
        Event addField(String name, String value);
    }

    /**
     * New event.
     *
     * @param monkeyType
     *            the monkey type
     * @param eventType
     *            the event type
     * @param region
     *            the region the event occurred
     * @param id
     *            the id
     * @return the event
     */
    Event newEvent(MonkeyType monkeyType, EventType eventType, String region, String id);

    default Event newEvent(MonkeyType monkeyType, EventType eventType, Resource resource, String id) {
        if (resource == null) throw new IllegalArgumentException("resource must not be null");
        Event event = newEvent(monkeyType, eventType, resource.getRegion(), id);
        if (resource.getAllTagKeys() != null) {
            for(String key : resource.getAllTagKeys()) {
                event.addField(key, resource.getTag(key));
            }
        }
        event.addField("ResourceDescription", resource.getDescription());
        event.addField("ResourceType", resource.getResourceType().toString());
        event.addField("ResourceId", resource.getId());
        return event;
    }

    /**
     * Record event.
     *
     * @param evt
     *            the evt
     */
    void recordEvent(Event evt);

    /**
     * Find events.
     *
     * @param query
     *            arbitrary map of strings to used to filter the results
     * @param after
     *            the after
     * @return the list of events
     */
    List<Event> findEvents(Map<String, String> query, Date after);

    /**
     * Find events.
     *
     * @param monkeyType
     *            the monkey type
     * @param query
     *            arbitrary map of strings to used to filter the results
     * @param after
     *            the after
     * @return the list of events
     */
    List<Event> findEvents(MonkeyType monkeyType, Map<String, String> query, Date after);

    /**
     * Find events.
     *
     * @param monkeyType
     *            the monkey type
     * @param eventType
     *            the event type
     * @param query
     *            arbitrary map of strings to used to filter the results
     * @param after
     *            the after
     * @return the list
     */
    List<Event> findEvents(MonkeyType monkeyType, EventType eventType, Map<String, String> query, Date after);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyRunner.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The MonkeyRunner Singleton.
 */
public enum MonkeyRunner {

    /** The instance. */
    INSTANCE;

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(MonkeyRunner.class);

    /**
     * Gets the single instance of MonkeyRunner.
     *
     * @return single instance of MonkeyRunner
     */
    public static MonkeyRunner getInstance() {
        return INSTANCE;
    }

    /**
     * Start all the monkeys registered with addMonkey or replaceMonkey.
     */
    public void start() {
        for (Monkey monkey : monkeys) {
            LOGGER.info("Starting " + monkey.type().name() + " Monkey");
            monkey.start();
        }
    }

    /**
     * Stop all of the registered monkeys.
     */
    public void stop() {
        for (Monkey monkey : monkeys) {
            LOGGER.info("Stopping " + monkey.type().name() + " Monkey");
            monkey.stop();
        }
    }

    /**
     * The monkey map. Maps the monkey class to the context class that is registered. This is so we can create new
     * monkeys in factory() that have the same context types as the registered ones.
     */
    private final Map<Class<? extends Monkey>, Class<? extends Monkey.Context>> monkeyMap =
            new HashMap<Class<? extends Monkey>, Class<? extends Monkey.Context>>();

    /** The monkeys. */
    private final List<Monkey> monkeys = new LinkedList<Monkey>();

    /**
     * Gets the registered monkeys.
     *
     * @return the monkeys
     */
    public List<Monkey> getMonkeys() {
        return Collections.unmodifiableList(monkeys);
    }

    /**
     * Adds a simple monkey void constructor.
     *
     * @param monkeyClass
     *            the monkey class
     */
    public void addMonkey(Class<? extends Monkey> monkeyClass) {
        addMonkey(monkeyClass, null);
    }

    /**
     * Replace a simple monkey that has void constructor.
     *
     * @param monkeyClass
     *            the monkey class
     */
    public void replaceMonkey(Class<? extends Monkey> monkeyClass) {
        replaceMonkey(monkeyClass, null);
    }

    /**
     * Adds the monkey.
     *
     * @param monkeyClass
     *            the monkey class
     * @param ctxClass
     *            the context class that is passed to the monkey class constructor.
     */
    public void addMonkey(Class<? extends Monkey> monkeyClass, Class<? extends Monkey.Context> ctxClass) {
        if (monkeyMap.containsKey(monkeyClass)) {
            throw new RuntimeException(monkeyClass.getName()
                    + " already registered, use replaceMonkey instead of addMonkey");
        }
        monkeyMap.put(monkeyClass, ctxClass);
        monkeys.add(factory(monkeyClass, ctxClass));
    }

    /**
     * Replace monkey. If a monkey is already registered this will replace that registered monkey.
     *
     * @param monkeyClass
     *            the monkey class
     * @param ctxClass
     *            the context class that is passed to the monkey class constructor.
     */
    public void replaceMonkey(Class<? extends Monkey> monkeyClass, Class<? extends Monkey.Context> ctxClass) {
        monkeyMap.put(monkeyClass, ctxClass);
        ListIterator<Monkey> li = monkeys.listIterator();
        while (li.hasNext()) {
            Monkey monkey = li.next();
            if (monkey.getClass() == monkeyClass) {
                li.set(factory(monkeyClass, ctxClass));
                return;
            }
        }
        Monkey monkey = factory(monkeyClass, ctxClass);
        monkeys.add(monkey);
    }

    /**
     * Removes the monkey. factory() will no longer be able to construct monkeys of the specified monkey class.
     *
     * @param monkeyClass
     *            the monkey class
     */
    public void removeMonkey(Class<? extends Monkey> monkeyClass) {
        ListIterator<Monkey> li = monkeys.listIterator();
        while (li.hasNext()) {
            Monkey monkey = li.next();
            if (monkey.getClass() == monkeyClass) {
                monkey.stop();
                li.remove();
                break;
            }
        }
        monkeyMap.remove(monkeyClass);
    }

    /**
     * Monkey factory. This will generate a new monkey object of the monkeyClass type. If a monkey of monkeyClass has
     * not been registered then this will attempt to find a registered subclass and create an object of that type.
     * Example:
     *
     * <pre>
     *         {@code
     *         MonkeyRunner.getInstance().addMonkey(BasicChaosMonkey.class, BasicMonkeyContext.class);
     *         // This will actually return a BasicChaosMonkey since that is the only subclass that was registered
     *         ChaosMonkey monkey = MonkeyRunner.getInstance().factory(ChaosMonkey.class);
     *}
     * </pre>
     *
     * @param <T>
     *            the generic type, must be a subclass of Monkey
     * @param monkeyClass
     *            the monkey class
     * @return the monkey
     */
    public <T extends Monkey> T factory(Class<T> monkeyClass) {
        Class<? extends Monkey.Context> ctxClass = getContextClass(monkeyClass);
        if (ctxClass == null) {
            // look for derived class already in our map
            for (Map.Entry<Class<? extends Monkey>, Class<? extends Monkey.Context>> pair : monkeyMap.entrySet()) {
                if (monkeyClass.isAssignableFrom(pair.getKey())) {
                    @SuppressWarnings("unchecked")
                    T monkey = (T) factory(pair.getKey(), pair.getValue());
                    return monkey;
                }
            }
        }
        return factory(monkeyClass, ctxClass);
    }

    /**
     * Monkey Factory. Given a monkey class and a monkey context class it will generate a new monkey. If the
     * contextClass is null it will try to generate a new monkeyClass with a void constructor;
     *
     * @param <T>
     *            the generic type, must be a subclass of Monkey
     * @param monkeyClass
     *            the monkey class
     * @param contextClass
     *            the context class
     * @return the monkey
     */
    public <T extends Monkey> T factory(Class<T> monkeyClass, Class<? extends Monkey.Context> contextClass) {
        try {
            if (contextClass == null) {
                // assume Monkey class has has void ctor
                return monkeyClass.newInstance();
            }

            // then find corresponding ctor
            for (Constructor<?> ctor : monkeyClass.getDeclaredConstructors()) {
                Class<?>[] paramTypes = ctor.getParameterTypes();
                if (paramTypes.length != 1) {
                    continue;
                }
                if (paramTypes[0].getName().endsWith("$Context")) {
                    @SuppressWarnings("unchecked")
                    T monkey = (T) ctor.newInstance(contextClass.newInstance());
                    return monkey;
                }
            }
        } catch (Exception e) {
            LOGGER.error("monkeyFactory error, cannot make monkey from " + monkeyClass.getName() + " with "
                    + (contextClass == null ? null : contextClass.getName()), e);
        }

        return null;
    }

    /**
     * Gets the context class. You should not need this.
     *
     * @param monkeyClass
     *            the monkey class
     * @return the context class or null if a monkeyClass has not been registered
     */
    public Class<? extends Monkey.Context> getContextClass(Class<? extends Monkey> monkeyClass) {
        return monkeyMap.get(monkeyClass);
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyScheduler.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

import java.util.concurrent.TimeUnit;

/**
 * The Interface MonkeyScheduler.
 */
public interface MonkeyScheduler {

    /**
     * Frequency. How often the monkey should run, works in conjunction with frequencyUnit(). If frequency is 2 and
     * frequencyUnit is TimeUnit.HOUR then the monkey will run once ever 2 hours.
     *
     * @return the frequency interval
     */
    int frequency();

    /**
     * Frequency unit. This is the time unit that corresponds with frequency().
     *
     * @return time unit
     */
    TimeUnit frequencyUnit();

    /**
     * Start the scheduler to cause the monkey run at a specified interval.
     *
     * @param monkey
     *            the monkey being scheduled
     * @param run
     *            the Runnable to start, generally calls doMonkeyBusiness
     */
    void start(Monkey monkey, Runnable run);

    /**
     * Stop the scheduler for a given monkey. After this the monkey will no longer run on the fixed schedule.
     *
     * @param monkey
     *            the monkey being scheduled
     */
    void stop(Monkey monkey);
}


================================================
FILE: src/main/java/com/netflix/simianarmy/MonkeyType.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * Marker interface for all monkey type enumerations.
 */
public interface MonkeyType extends NamedType {

}


================================================
FILE: src/main/java/com/netflix/simianarmy/NamedType.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * Interface requiring a name() method.
 */
public interface NamedType {

    /**
     * Name of this instance.
     */
    String name();

}


================================================
FILE: src/main/java/com/netflix/simianarmy/NotFoundException.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * The Class NotFoundException.
 *
 * These exceptions will be thrown when a Monkey is trying to interact with a remote resource but it no longer exists
 * (or never existed). It is used as an adapter to translate a cloud provider exception into something common that the
 * monkeys can easily handle.
 */
@SuppressWarnings("serial")
public class NotFoundException extends RuntimeException {

    /**
     * Instantiates a new NotFound exception.
     *
     * @param message
     *            the exception message
     */
    public NotFoundException(String message) {
        super(message);
    }

    /**
     * Instantiates a new NotFound exception.
     *
     * @param message
     *            the exception message
     * @param cause
     *            the exception cause. This should be the raw exception from the cloud provider.
     */
    public NotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Instantiates a new NotFound exception.
     *
     * @param cause
     *            the exception cause. This should be the raw exception from the cloud provider.
     */
    public NotFoundException(Throwable cause) {
        super(cause);
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/Resource.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy;

import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * The interface of Resource. It defines the interfaces for getting the common properties of a resource, as well as
 * the methods to add and retrieve the additional properties of a resource. Instead of defining a new subclass of
 * the Resource interface, new resources that have additional fields other than the common ones can be represented,
 * by adding field-value pairs. This approach makes serialization and deserialization of resources much easier with
 * the cost of type safety.
 */
public interface Resource {
    /** The enum representing the cleanup state of a resource. **/
    public enum CleanupState {
        /** The resource is marked as a cleanup candidate but has not been cleaned up yet. **/
        MARKED,
        /** The resource is terminated by janitor monkey. **/
        JANITOR_TERMINATED,
        /** The resource is terminated by user before janitor monkey performs the termination. **/
        USER_TERMINATED,
        /** The resource is unmarked and not for cleanup anymore due to some change of situations. **/
        UNMARKED
    }

    /**
     * Gets the resource id.
     *
     * @return the resource id
     */
    String getId();

    /**
     * Sets the resource id.
     *
     * @param id the resource id
     */
    void setId(String id);

    /**
     * Sets the resource id and returns the resource.
     *
     * @param id the resource id
     * @return the resource object
     */
    Resource withId(String id);

    /**
     * Gets the resource type.
     *
     * @return the resource type enum
     */
    ResourceType getResourceType();

    /**
     * Sets the resource type.
     *
     * @param type the resource type enum
     */
    void setResourceType(ResourceType type);

    /**
     * Sets the resource type and returns the resource.
     *
     * @param type resource type enum
     * @return the resource object
     */
    Resource withResourceType(ResourceType type);

    /**
     * Gets the region the resource is in.
     *
     * @return the region of the resource
     */
    String getRegion();

    /**
     * Sets the region the resource is in.
     *
     * @param region the region the resource is in
     */
    void setRegion(String region);

    /**
     * Sets the resource region and returns the resource.
     *
     * @param region the region the resource is in
     * @return the resource object
     */
    Resource withRegion(String region);

    /**
     * Gets the owner email of the resource.
     *
     * @return the owner email of the resource
     */
    String getOwnerEmail();

    /**
     * Sets the owner email of the resource.
     *
     * @param ownerEmail the owner email of the resource
     */
    void setOwnerEmail(String ownerEmail);

    /**
     * Sets the resource owner email and returns the resource.
     *
     * @param ownerEmail the owner email of the resource
     * @return the resource object
     */
    Resource withOwnerEmail(String ownerEmail);

    /**
     * Gets the description of the resource.
     *
     * @return the description of the resource
     */
    String getDescription();

    /**
     * Sets the description of the resource.
     *
     * @param description the description of the resource
     */
    void setDescription(String description);

    /**
     * Sets the resource description and returns the resource.
     *
     * @param description the description of the resource
     * @return the resource object
     */
    Resource withDescription(String description);

    /**
     * Gets the launch time of the resource.
     *
     * @return the launch time of the resource
     */
    Date getLaunchTime();

    /**
     * Sets the launch time of the resource.
     *
     * @param launchTime the launch time of the resource
     */
    void setLaunchTime(Date launchTime);

    /**
     * Sets the resource launch time and returns the resource.
     *
     * @param launchTime the launch time of the resource
     * @return the resource object
     */
    Resource withLaunchTime(Date launchTime);

    /**
     * Gets the time that when the resource is marked as a cleanup candidate.
     *
     * @return the time that when the resource is marked as a cleanup candidate
     */
    Date getMarkTime();

    /**
     * Sets the time that when the resource is marked as a cleanup candidate.
     *
     * @param markTime the time that when the resource is marked as a cleanup candidate
     */
    void setMarkTime(Date markTime);

    /**
     * Sets the resource mark time and returns the resource.
     *
     * @param markTime the time that when the resource is marked as a cleanup candidate
     * @return the resource object
     */
    Resource withMarkTime(Date markTime);

    /**
     * Gets the the time that when the resource is expected to be terminated.
     *
     * @return the time that when the resource is expected to be terminated
     */
    Date getExpectedTerminationTime();

    /**
     * Sets the time that when the resource is expected to be terminated.
     *
     * @param expectedTerminationTime the time that when the resource is expected to be terminated
     */
    void setExpectedTerminationTime(Date expectedTerminationTime);

    /**
     * Sets the time that when the resource is expected to be terminated and returns the resource.
     *
     * @param expectedTerminationTime the time that when the resource is expected to be terminated
     * @return the resource object
     */
    Resource withExpectedTerminationTime(Date expectedTerminationTime);

    /**
     * Gets the time that when the resource is actually terminated.
     *
     * @return the time that when the resource is actually terminated
     */
    Date getActualTerminationTime();

    /**
     * Sets the time that when the resource is actually terminated.
     *
     * @param actualTerminationTime the time that when the resource is actually terminated
     */
    void setActualTerminationTime(Date actualTerminationTime);

    /**
     * Sets the resource actual termination time and returns the resource.
     *
     * @param actualTerminationTime the time that when the resource is actually terminated
     * @return the resource object
     */
    Resource withActualTerminationTime(Date actualTerminationTime);

    /**
     * Gets the time that when the owner is notified about the cleanup of the resource.
     *
     * @return the time that when the owner is notified about the cleanup of the resource
     */
    Date getNotificationTime();

    /**
     * Sets the time that when the owner is notified about the cleanup of the resource.
     *
     * @param notificationTime the time that when the owner is notified about the cleanup of the resource
     */
    void setNotificationTime(Date notificationTime);

    /**
     * Sets the time that when the owner is notified about the cleanup of the resource and returns the resource.
     *
     * @param notificationTime the time that when the owner is notified about the cleanup of the resource
     * @return the resource object
     */
    Resource withNnotificationTime(Date notificationTime);

    /**
     * Gets the resource state.
     *
     * @return the resource state enum
     */
    CleanupState getState();

    /**
     * Sets the resource state.
     *
     * @param state the resource state
     */
    void setState(CleanupState state);

    /**
     * Sets the resource state and returns the resource.
     *
     * @param state resource state enum
     * @return the resource object
     */
    Resource withState(CleanupState state);

    /**
     * Gets the termination reason of the resource.
     *
     * @return the termination reason of the resource
     */
    String getTerminationReason();

    /**
     * Sets the termination reason of the resource.
     *
     * @param terminationReason the termination reason of the resource
     */
    void setTerminationReason(String terminationReason);

    /**
     * Sets the resource termination reason and returns the resource.
     *
     * @param terminationReason the termination reason of the resource
     * @return the resource object
     */
    Resource withTerminationReason(String terminationReason);

    /**
     * Gets the boolean to indicate whether or not the resource is opted out of Janitor monkey
     * so it will not be cleaned.
     * @return true if the resource is opted out of Janitor monkey, otherwise false
     */
    boolean isOptOutOfJanitor();

    /**
     * Sets the flag to indicate whether or not the resource is opted out of Janitor monkey
     * so it will not be cleaned.
     * @param optOutOfJanitor true if the resource is opted out of Janitor monkey, otherwise false
     */
    void setOptOutOfJanitor(boolean optOutOfJanitor);

    /**
     * Sets the flag to indicate whether or not the resource is opted out of Janitor monkey
     * so it will not be cleaned and returns the resource object.
     * @param optOutOfJanitor true if the resource is opted out of Janitor monkey, otherwise false
     * @return the resource object
     */
    Resource withOptOutOfJanitor(boolean optOutOfJanitor);

    /**
     * Gets a map from fields of resources to corresponding values. Values are represented
     * as Strings so they can be displayed or stored in databases like SimpleDB.
     * @return a map from field name to field value
     */
    Map<String, String> getFieldToValueMap();

    /** Adds or sets an additional field with the specified name and value to the resource.
     *
     * @param fieldName the field name
     * @param fieldValue the field value
     * @return the resource itself for chaining
     */
    Resource setAdditionalField(String fieldName, String fieldValue);

    /** Gets the value of an additional field with the specified name of the resource.
     *
     * @param fieldName the field name
     * @return the field value
     */
    String getAdditionalField(String fieldName);

    /**
     * Gets all additional field names in the resource.
     * @return a collection of names of all additional fields
     */
    Collection<String> getAdditionalFieldNames();

    /**
     * Adds a tag with the specified key and value to the resource.
     * @param key the key of the tag
     * @param value the value of the tag
     */
    void setTag(String key, String value);

    /**
     * Gets the tag value for a specific key of the resource.
     * @param key the key of the tag
     * @return the value of the tag
     */
    String getTag(String key);

    /**
     * Gets all the keys of tags.
     * @return collection of keys of all tags
     */
    Collection<String> getAllTagKeys();


    /** Clone a resource with the exact field values of the current object.
     *
     * @return the clone of the resource
     */
    Resource cloneResource();
}


================================================
FILE: src/main/java/com/netflix/simianarmy/ResourceType.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy;

/**
 * Marker interface for all resource type enumerations.
 */
public interface ResourceType extends NamedType {

}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/AWSEmailNotifier.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy.aws;

import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.Body;
import com.amazonaws.services.simpleemail.model.Content;
import com.amazonaws.services.simpleemail.model.Destination;
import com.amazonaws.services.simpleemail.model.Message;
import com.amazonaws.services.simpleemail.model.SendEmailRequest;
import com.amazonaws.services.simpleemail.model.SendEmailResult;
import com.netflix.simianarmy.MonkeyEmailNotifier;

/**
 * The class implements the monkey email notifier using AWS simple email service
 * for sending email.
 */
public abstract class AWSEmailNotifier implements MonkeyEmailNotifier {
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(AWSEmailNotifier.class);
    private static final String EMAIL_PATTERN =
            "^[_A-Za-z0-9-\\+\\.#]+(.[_A-Za-z0-9-#]+)*@"
                    + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

    private final Pattern emailPattern;

    private final AmazonSimpleEmailServiceClient sesClient;

    /**
     * The constructor.
     */
    public AWSEmailNotifier(AmazonSimpleEmailServiceClient sesClient) {
        super();
        this.sesClient = sesClient;
        this.emailPattern = Pattern.compile(EMAIL_PATTERN);
    }

    @Override
    public void sendEmail(String to, String subject, String body) {
        if (!isValidEmail(to)) {
            LOGGER.error(String.format("The destination email address %s is not valid, no email is sent.", to));
            return;
        }
        if (sesClient == null) {
            String msg = "The email client is not set.";
            LOGGER.error(msg);
            throw new RuntimeException(msg);
        }
        Destination destination = new Destination().withToAddresses(to)
                .withCcAddresses(getCcAddresses(to));
        Content subjectContent = new Content(subject);
        Content bodyContent = new Content();
        Body msgBody = new Body(bodyContent);
        msgBody.setHtml(new Content(body));
        Message msg = new Message(subjectContent, msgBody);
        String sourceAddress = getSourceAddress(to);
        SendEmailRequest request = new SendEmailRequest(sourceAddress, destination, msg);
        request.setReturnPath(sourceAddress);
        LOGGER.debug(String.format("Sending email with subject '%s' to %s",
                subject, to));
        SendEmailResult result = null;
        try {
            result = sesClient.sendEmail(request);
        } catch (Exception e) {
            throw new RuntimeException(String.format("Failed to send email to %s", to), e);
        }
        LOGGER.info(String.format("Email to %s, result id is %s, subject is %s",
                to, result.getMessageId(), subject));
    }

    @Override
    public boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        if (!emailPattern.matcher(email).matches()) {
            LOGGER.error(String.format("Invalid email address: %s", email));
            return false;
        }
        if (email.equals("foo@bar.com")) {
            LOGGER.error(String.format("Email address not changed from default; treating as invalid: %s", email));
            return false;
        }
        return true;
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/AWSResource.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy.aws;

import java.util.*;

import org.apache.commons.lang.Validate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.netflix.simianarmy.NamedType;
import com.netflix.simianarmy.Resource;
import com.netflix.simianarmy.ResourceType;

/**
 * The class represents general AWS resources that are managed by janitor monkey.
 */
public class AWSResource implements Resource {
    private String id;
    private ResourceType resourceType;
    private String region;
    private String ownerEmail;
    private String description;
    private String terminationReason;
    private CleanupState state;
    private Date expectedTerminationTime;
    private Date actualTerminationTime;
    private Date notificationTime;
    private Date launchTime;
    private Date markTime;
    private boolean optOutOfJanitor;
    private String awsResourceState;

    /** The field name for resourceId. **/
    public static final String FIELD_RESOURCE_ID = "resourceId";
    /** The field name for resourceType. **/
    public static final String FIELD_RESOURCE_TYPE = "resourceType";
    /** The field name for region. **/
    public static final String FIELD_REGION = "region";
    /** The field name for owner email. **/
    public static final String FIELD_OWNER_EMAIL = "ownerEmail";
    /** The field name for description. **/
    public static final String FIELD_DESCRIPTION = "description";
    /** The field name for state. **/
    public static final String FIELD_STATE = "state";
    /** The field name for terminationReason. **/
    public static final String FIELD_TERMINATION_REASON = "terminationReason";
    /** The field name for expectedTerminationTime. **/
    public static final String FIELD_EXPECTED_TERMINATION_TIME = "expectedTerminationTime";
    /** The field name for actualTerminationTime. **/
    public static final String FIELD_ACTUAL_TERMINATION_TIME = "actualTerminationTime";
    /** The field name for notificationTime. **/
    public static final String FIELD_NOTIFICATION_TIME = "notificationTime";
    /** The field name for launchTime. **/
    public static final String FIELD_LAUNCH_TIME = "launchTime";
    /** The field name for markTime. **/
    public static final String FIELD_MARK_TIME = "markTime";
    /** The field name for isOptOutOfJanitor. **/
    public static final String FIELD_OPT_OUT_OF_JANITOR = "optOutOfJanitor";
    /** The field name for awsResourceState. **/
    public static final String FIELD_AWS_RESOURCE_STATE = "awsResourceState";

    /** The date format used to print or parse a Date value. **/
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss");

    /** The map from name to value for additional fields used by the resource. **/
    private final Map<String, String> additionalFields = new HashMap<String, String>();

    /** The map from AWS tag key to value for the resource. **/
    private final Map<String, String> tags = new HashMap<String, String>();

    /** {@inheritDoc} */
    @Override
    public Map<String, String> getFieldToValueMap() {
        Map<String, String> fieldToValue = new HashMap<String, String>();

        putToMapIfNotNull(fieldToValue, FIELD_RESOURCE_ID, getId());
        putToMapIfNotNull(fieldToValue, FIELD_RESOURCE_TYPE, getResourceType());
        putToMapIfNotNull(fieldToValue, FIELD_REGION, getRegion());
        putToMapIfNotNull(fieldToValue, FIELD_OWNER_EMAIL, getOwnerEmail());
        putToMapIfNotNull(fieldToValue, FIELD_DESCRIPTION, getDescription());
        putToMapIfNotNull(fieldToValue, FIELD_STATE, getState());
        putToMapIfNotNull(fieldToValue, FIELD_TERMINATION_REASON, getTerminationReason());
        putToMapIfNotNull(fieldToValue, FIELD_EXPECTED_TERMINATION_TIME, printDate(getExpectedTerminationTime()));
        putToMapIfNotNull(fieldToValue, FIELD_ACTUAL_TERMINATION_TIME, printDate(getActualTerminationTime()));
        putToMapIfNotNull(fieldToValue, FIELD_NOTIFICATION_TIME, printDate(getNotificationTime()));
        putToMapIfNotNull(fieldToValue, FIELD_LAUNCH_TIME, printDate(getLaunchTime()));
        putToMapIfNotNull(fieldToValue, FIELD_MARK_TIME, printDate(getMarkTime()));
        putToMapIfNotNull(fieldToValue, FIELD_AWS_RESOURCE_STATE, getAWSResourceState());

        // Additional fields are serialized while tags are not. So if any tags need to be
        // serialized as well, put them to additional fields.
        fieldToValue.put(FIELD_OPT_OUT_OF_JANITOR, String.valueOf(isOptOutOfJanitor()));

        fieldToValue.putAll(additionalFields);

        return fieldToValue;
    }

    /**
     * Parse a map from field name to value to a resource.
     * @param fieldToValue the map from field name to value
     * @return the resource that is de-serialized from the map
     */
    public static AWSResource parseFieldtoValueMap(Map<String, String> fieldToValue) {
        AWSResource resource = new AWSResource();
        for (Map.Entry<String, String> field : fieldToValue.entrySet()) {
            String name = field.getKey();
            String value = field.getValue();
            if (name.equals(FIELD_RESOURCE_ID)) {
                resource.setId(value);
            } else if (name.equals(FIELD_RESOURCE_TYPE)) {
                resource.setResourceType(AWSResourceType.valueOf(value));
            } else if (name.equals(FIELD_REGION)) {
                resource.setRegion(value);
            } else if (name.equals(FIELD_OWNER_EMAIL)) {
                resource.setOwnerEmail(value);
            } else if (name.equals(FIELD_DESCRIPTION)) {
                resource.setDescription(value);
            } else if (name.equals(FIELD_STATE)) {
                resource.setState(CleanupState.valueOf(value));
            } else if (name.equals(FIELD_TERMINATION_REASON)) {
                resource.setTerminationReason(value);
            } else if (name.equals(FIELD_EXPECTED_TERMINATION_TIME)) {
                resource.setExpectedTerminationTime(new Date(DATE_FORMATTER.parseDateTime(value).getMillis()));
            } else if (name.equals(FIELD_ACTUAL_TERMINATION_TIME)) {
                resource.setActualTerminationTime(new Date(DATE_FORMATTER.parseDateTime(value).getMillis()));
            } else if (name.equals(FIELD_NOTIFICATION_TIME)) {
                resource.setNotificationTime(new Date(DATE_FORMATTER.parseDateTime(value).getMillis()));
            } else if (name.equals(FIELD_LAUNCH_TIME)) {
                resource.setLaunchTime(new Date(DATE_FORMATTER.parseDateTime(value).getMillis()));
            } else if (name.equals(FIELD_MARK_TIME)) {
                resource.setMarkTime(new Date(DATE_FORMATTER.parseDateTime(value).getMillis()));
            } else if (name.equals(FIELD_AWS_RESOURCE_STATE)) {
                resource.setAWSResourceState(value);
            } else if (name.equals(FIELD_OPT_OUT_OF_JANITOR)) {
                resource.setOptOutOfJanitor("true".equals(value));
            } else {
                // put all other fields into additional fields
                resource.setAdditionalField(name, value);
            }
        }
        return resource;
    }

    public String getAWSResourceState() {
        return awsResourceState;
    }

    public void setAWSResourceState(String awsState) {
        this.awsResourceState = awsState;
    }

    /** {@inheritDoc} */
    @Override
    public String getId() {
        return id;
    }

    /** {@inheritDoc} */
    @Override
    public void setId(String id) {
        this.id = id;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withId(String resourceId) {
        setId(resourceId);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public ResourceType getResourceType() {
        return resourceType;
    }

    /** {@inheritDoc} */
    @Override
    public void setResourceType(ResourceType resourceType) {
        this.resourceType = resourceType;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withResourceType(ResourceType type) {
        setResourceType(type);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public String getRegion() {
        return region;
    }

    /** {@inheritDoc} */
    @Override
    public void setRegion(String region) {
        this.region = region;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withRegion(String resourceRegion) {
        setRegion(resourceRegion);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public String getOwnerEmail() {
        return ownerEmail;
    }

    /** {@inheritDoc} */
    @Override
    public void setOwnerEmail(String ownerEmail) {
        this.ownerEmail = ownerEmail;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withOwnerEmail(String resourceOwner) {
        setOwnerEmail(resourceOwner);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public String getDescription() {
        return description;
    }

    /** {@inheritDoc} */
    @Override
    public void setDescription(String description) {
        this.description = description;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withDescription(String resourceDescription) {
        setDescription(resourceDescription);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public Date getLaunchTime() {
        return getCopyOfDate(launchTime);
    }

    /** {@inheritDoc} */
    @Override
    public void setLaunchTime(Date launchTime) {
        this.launchTime = getCopyOfDate(launchTime);
    }

    /** {@inheritDoc} */
    @Override
    public Resource withLaunchTime(Date resourceLaunchTime) {
        setLaunchTime(resourceLaunchTime);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public Date getMarkTime() {
        return getCopyOfDate(markTime);
    }

    /** {@inheritDoc} */
    @Override
    public void setMarkTime(Date markTime) {
        this.markTime = getCopyOfDate(markTime);
    }

    /** {@inheritDoc} */
    @Override
    public Resource withMarkTime(Date resourceMarkTime) {
        setMarkTime(resourceMarkTime);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public Date getExpectedTerminationTime() {
        return getCopyOfDate(expectedTerminationTime);
    }

    /** {@inheritDoc} */
    @Override
    public void setExpectedTerminationTime(Date expectedTerminationTime) {
        this.expectedTerminationTime = getCopyOfDate(expectedTerminationTime);
    }

    /** {@inheritDoc} */
    @Override
    public Resource withExpectedTerminationTime(Date resourceExpectedTerminationTime) {
        setExpectedTerminationTime(resourceExpectedTerminationTime);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public Date getActualTerminationTime() {
        return getCopyOfDate(actualTerminationTime);
    }

    /** {@inheritDoc} */
    @Override
    public void setActualTerminationTime(Date actualTerminationTime) {
        this.actualTerminationTime = getCopyOfDate(actualTerminationTime);
    }

    /** {@inheritDoc} */
    @Override
    public Resource withActualTerminationTime(Date resourceActualTerminationTime) {
        setActualTerminationTime(resourceActualTerminationTime);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public Date getNotificationTime() {
        return getCopyOfDate(notificationTime);
    }

    /** {@inheritDoc} */
    @Override
    public void setNotificationTime(Date notificationTime) {
        this.notificationTime = getCopyOfDate(notificationTime);
    }

    /** {@inheritDoc} */
    @Override
    public Resource withNnotificationTime(Date resourceNotificationTime) {
        setNotificationTime(resourceNotificationTime);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public CleanupState getState() {
        return state;
    }

    /** {@inheritDoc} */
    @Override
    public void setState(CleanupState state) {
        this.state = state;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withState(CleanupState resourceState) {
        setState(resourceState);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public String getTerminationReason() {
        return terminationReason;
    }

    /** {@inheritDoc} */
    @Override
    public void setTerminationReason(String terminationReason) {
        this.terminationReason = terminationReason;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withTerminationReason(String resourceTerminationReason) {
        setTerminationReason(resourceTerminationReason);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isOptOutOfJanitor() {
        return optOutOfJanitor;
    }

    /** {@inheritDoc} */
    @Override
    public void setOptOutOfJanitor(boolean optOutOfJanitor) {
        this.optOutOfJanitor = optOutOfJanitor;
    }

    /** {@inheritDoc} */
    @Override
    public Resource withOptOutOfJanitor(boolean optOut) {
        setOptOutOfJanitor(optOut);
        return this;
    }

    private static Date getCopyOfDate(Date date) {
        if (date == null) {
            return null;
        }
        return new Date(date.getTime());
    }

    private static void putToMapIfNotNull(Map<String, String> map, String key, String value) {
        Validate.notNull(map);
        Validate.notNull(key);
        if (value != null) {
            map.put(key, value);
        }
    }

    private static void putToMapIfNotNull(Map<String, String> map, String key, Enum<?> value) {
        Validate.notNull(map);
        Validate.notNull(key);
        if (value != null) {
            map.put(key, value.name());
        }
    }

    private static void putToMapIfNotNull(Map<String, String> map, String key, NamedType value) {
        Validate.notNull(map);
        Validate.notNull(key);
        if (value != null) {
            map.put(key, value.name());
        }
    }

    private static String printDate(Date date) {
        if (date == null) {
            return null;
        }

        return DATE_FORMATTER.print(date.getTime());
    }

    @Override
    public Resource setAdditionalField(String fieldName, String fieldValue) {
        Validate.notNull(fieldName);
        Validate.notNull(fieldValue);
        putToMapIfNotNull(additionalFields, fieldName, fieldValue);
        return this;
    }

    @Override
    public String getAdditionalField(String fieldName) {
        return additionalFields.get(fieldName);
    }

    @Override
    public Collection<String> getAdditionalFieldNames() {
        return additionalFields.keySet();
    }

    @Override
    public Resource cloneResource() {
        Resource clone = new AWSResource()
        .withActualTerminationTime(getActualTerminationTime())
        .withDescription(getDescription())
        .withExpectedTerminationTime(getExpectedTerminationTime())
        .withId(getId())
        .withLaunchTime(getLaunchTime())
        .withMarkTime(getMarkTime())
        .withNnotificationTime(getNotificationTime())
        .withOwnerEmail(getOwnerEmail())
        .withRegion(getRegion())
        .withResourceType(getResourceType())
        .withState(getState())
        .withTerminationReason(getTerminationReason())
        .withOptOutOfJanitor(isOptOutOfJanitor());
        ((AWSResource) clone).setAWSResourceState(awsResourceState);

        ((AWSResource) clone).additionalFields.putAll(additionalFields);

        for (String key : this.getAllTagKeys()) {
            clone.setTag(key, this.getTag(key));
        }

        return clone;
    }

    /** {@inheritDoc} */
    @Override
    public void setTag(String key, String value) {
        tags.put(key, value);
    }

    /** {@inheritDoc} */
    @Override
    public String getTag(String key) {
        return tags.get(key);
    }

    /** {@inheritDoc} */
    @Override
    public Collection<String> getAllTagKeys() {
        return tags.keySet();
    }

    @Override
    public String toString() {
        return "AWSResource{" +
                "id='" + id + '\'' +
                ", resourceType=" + resourceType +
                ", region='" + region + '\'' +
                ", ownerEmail='" + ownerEmail + '\'' +
                ", description='" + description + '\'' +
                ", terminationReason='" + terminationReason + '\'' +
                ", state=" + state +
                ", expectedTerminationTime=" + expectedTerminationTime +
                ", actualTerminationTime=" + actualTerminationTime +
                ", notificationTime=" + notificationTime +
                ", launchTime=" + launchTime +
                ", markTime=" + markTime +
                ", optOutOfJanitor=" + optOutOfJanitor +
                ", awsResourceState='" + awsResourceState + '\'' +
                ", additionalFields=" + additionalFields +
                ", tags=" + tags +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        // consider two resources to be equivalent if id, resourceType and region match
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AWSResource that = (AWSResource) o;
        return Objects.equals(id, that.id) &&
                Objects.equals(resourceType, that.resourceType) &&
                Objects.equals(region, that.region);
    }

    @Override
    public int hashCode() {
        // consider two resources to be equivalent if id, resourceType and region match
        return Objects.hash(id, resourceType, region);
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/AWSResourceType.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

package com.netflix.simianarmy.aws;

import com.netflix.simianarmy.ResourceType;

/**
 * The enum of resource types of AWS.
 */
public enum AWSResourceType implements ResourceType {
    /** AWS instance. */
    INSTANCE,
    /** AWS EBS volume. */
    EBS_VOLUME,
    /** AWS EBS snapshot. */
    EBS_SNAPSHOT,
    /** AWS auto scaling group. */
    ASG,
    /** AWS launch configuration. */
    LAUNCH_CONFIG,
    /** AWS S3 bucket. */
    S3_BUCKET,
    /** AWS security group. */
    SECURITY_GROUP,
    /** AWS Amazon Machine Image. **/
    IMAGE,
    /** AWS Elastic Load Balancer. **/
    ELB
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/RDSRecorder.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws;

import com.amazonaws.AmazonClientException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.simianarmy.EventType;
import com.netflix.simianarmy.MonkeyRecorder;
import com.netflix.simianarmy.MonkeyType;
import com.netflix.simianarmy.basic.BasicRecorderEvent;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * The Class RDSRecorder. Records events to and fetched events from a RDS table (default SIMIAN_ARMY)
 */
@SuppressWarnings("serial")
public class RDSRecorder implements MonkeyRecorder {
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(RDSRecorder.class);

    private final String region;

    /** The table. */
    private final String table;
    
    /** the jdbcTemplate  */
    JdbcTemplate jdbcTemplate = null;

    public static final String FIELD_ID = "eventId";
    public static final String FIELD_EVENT_TIME = "eventTime";
    public static final String FIELD_MONKEY_TYPE = "monkeyType";
    public static final String FIELD_EVENT_TYPE = "eventType";
    public static final String FIELD_REGION = "region";
    public static final String FIELD_DATA_JSON = "dataJson";
        
    /**
     * Instantiates a new RDS recorder.
     *
     */
    public RDSRecorder(String dbDriver, String dbUser,
			String dbPass, String dbUrl, String dbTable, String region) {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(dbDriver);
        dataSource.setJdbcUrl(dbUrl);
        dataSource.setUsername(dbUser);
        dataSource.setPassword(dbPass);
        dataSource.setMaximumPoolSize(2);
    	this.jdbcTemplate = new JdbcTemplate(dataSource);
    	this.table = dbTable;
    	this.region = region;
    }

    /**
     * Instantiates a new RDS recorder.  This constructor is intended
     * for unit testing.
     *
     */
    public RDSRecorder(JdbcTemplate jdbcTemplate, String table, String region) {
    	this.jdbcTemplate = jdbcTemplate;
    	this.table = table;
    	this.region = region;
    }
    
    public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

    /** {@inheritDoc} */
    @Override
    public Event newEvent(MonkeyType monkeyType, EventType eventType, String reg, String id) {
        return new BasicRecorderEvent(monkeyType, eventType, reg, id);
    }

    /** {@inheritDoc} */
    @Override
    public void recordEvent(Event evt) {    	
        String evtTime = String.valueOf(evt.eventTime().getTime());
        String name = String.format("%s-%s-%s-%s", evt.monkeyType().name(), evt.id(), region, evtTime);
    	String json;
		try {
			json = new ObjectMapper().writeValueAsString(evt.fields());
		} catch (JsonProcessingException e) {
			LOGGER.error("ERROR generating JSON when saving resource " + name, e);
			return;
		}
        
        LOGGER.debug(String.format("Saving event %s to RDS table %s", name, table));    	        
		StringBuilder sb = new StringBuilder();
		sb.append("insert into ").append(table);
		sb.append(" (");
		sb.append(FIELD_ID).append(",");
		sb.append(FIELD_EVENT_TIME).append(",");
		sb.append(FIELD_MONKEY_TYPE).append(",");
		sb.append(FIELD_EVENT_TYPE).append(",");
		sb.append(FIELD_REGION).append(",");
		sb.append(FIELD_DATA_JSON).append(") values (?,?,?,?,?,?)");

        LOGGER.debug(String.format("Insert statement is '%s'", sb));
        int updated = this.jdbcTemplate.update(sb.toString(),
											   evt.id(),
											   evt.eventTime().getTime(),
											   SimpleDBRecorder.enumToValue(evt.monkeyType()),
											   SimpleDBRecorder.enumToValue(evt.eventType()),
											   evt.region(),
											   json);    	
        LOGGER.debug(String.format("%d rows inserted", updated));        
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(Map<String, String> query, Date after) {
        return findEvents(null, null, query, after);
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(MonkeyType monkeyType, Map<String, String> query, Date after) {
        return findEvents(monkeyType, null, query, after);
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(MonkeyType monkeyType, EventType eventType, Map<String, String> query, Date after) {
        ArrayList<Object> args = new ArrayList<>();
        StringBuilder sqlquery = new StringBuilder(
                String.format("select * from %s where region = ?", table));
        args.add(region);
        
        if (monkeyType != null) {
        	sqlquery.append(String.format(" and %s = ?", FIELD_MONKEY_TYPE));
        	args.add(SimpleDBRecorder.enumToValue(monkeyType));
        }

        if (eventType != null) {
        	sqlquery.append(String.format(" and %s = ?", FIELD_EVENT_TYPE));
        	args.add(SimpleDBRecorder.enumToValue(eventType));
        }
        
        for (Map.Entry<String, String> pair : query.entrySet()) {
        	sqlquery.append(String.format(" and %s like ?", FIELD_DATA_JSON));
            args.add((String.format("%s: \"%s\"", pair.getKey(), pair.getValue())));
        }
        sqlquery.append(String.format(" and %s > ? order by %s desc", FIELD_EVENT_TIME, FIELD_EVENT_TIME));
        args.add(new Long(after.getTime()));
        
        LOGGER.debug(String.format("Query is '%s'", sqlquery));
        List<Event> events = jdbcTemplate.query(sqlquery.toString(), args.toArray(), new RowMapper<Event>() {
            public Event mapRow(ResultSet rs, int rowNum) throws SQLException {
            	return mapEvent(rs);                
            }             
        });                
        return events;
    }
    
    private Event mapEvent(ResultSet rs) throws SQLException {
    	String json = rs.getString("dataJson");
    	ObjectMapper mapper = new ObjectMapper();
    	Event event = null;
    	try {
    		String id = rs.getString(FIELD_ID);
    		MonkeyType monkeyType = SimpleDBRecorder.valueToEnum(MonkeyType.class, rs.getString(FIELD_MONKEY_TYPE));
    		EventType eventType = SimpleDBRecorder.valueToEnum(EventType.class, rs.getString(FIELD_EVENT_TYPE));
    		String region = rs.getString(FIELD_REGION);
    		long time = rs.getLong(FIELD_EVENT_TIME);    		
    	    event = new BasicRecorderEvent(monkeyType, eventType, region, id, time);

            TypeReference<Map<String,String>> typeRef = new TypeReference<Map<String,String>>() {};
    		Map<String, String> map = mapper.readValue(json, typeRef);
    	    for(String key : map.keySet()) {
    	    	event.addField(key, map.get(key));
    	    }

    	}catch(IOException ie) {
    		LOGGER.error("Error parsing resource from json", ie);
    	}    	
        return event;
    }             
                   

    /**
     * Creates the RDS table, if it does not already exist.
     */
    public void init() {
        try {
            if (this.region == null || this.region.equals("region-null")) {
                // This is a mock with an invalid region; avoid a slow timeout
                LOGGER.debug("Region=null; skipping RDS table creation");
                return;
            }
            
            LOGGER.info("Creating RDS table: {}", table);
            String sql = String.format("create table if not exists %s ("
                                     + " %s varchar(255),"
                                     + " %s BIGINT,"
                                     + " %s varchar(255),"
                                     + " %s varchar(255),"
                                     + " %s varchar(255),"
                                     + " %s varchar(4096) )", 
                                     table, 
                                     FIELD_ID, 
                                     FIELD_EVENT_TIME, 
                                     FIELD_MONKEY_TYPE, 
                                     FIELD_EVENT_TYPE, 
                                     FIELD_REGION, 
                                     FIELD_DATA_JSON);
            LOGGER.debug("Create SQL is: '{}'", sql);
            jdbcTemplate.execute(sql);
            
        } catch (AmazonClientException e) {
            LOGGER.warn("Error while trying to auto-create RDS table", e);
        }
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/STSAssumeRoleSessionCredentialsProvider.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws;

import java.util.Date;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSSessionCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;

/**
 * AWSCredentialsProvider implementation that uses the AWS Security Token
 * Service to assume a Role and create temporary, short-lived sessions to use
 * for authentication.
 */
public class STSAssumeRoleSessionCredentialsProvider implements AWSCredentialsProvider {

    /** Default duration for started sessions. */
    public static final int DEFAULT_DURATION_SECONDS = 900;

    /** Time before expiry within which credentials will be renewed. */
    private static final int EXPIRY_TIME_MILLIS = 60 * 1000;

    /** The client for starting STS sessions. */
    private final AWSSecurityTokenService securityTokenService;

    /** The current session credentials. */
    private AWSSessionCredentials sessionCredentials;

    /** The expiration time for the current session credentials. */
    private Date sessionCredentialsExpiration;

    /** The arn of the role to be assumed. */
    private String roleArn;

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which makes a
     * request to the AWS Security Token Service (STS), uses the provided
     * {@link #roleArn} to assume a role and then request short lived session
     * credentials, which will then be returned by this class's
     * {@link #getCredentials()} method.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     */
    public STSAssumeRoleSessionCredentialsProvider(String roleArn) {
        this.roleArn = roleArn;
        securityTokenService = new AWSSecurityTokenServiceClient();
    }

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which makes a
     * request to the AWS Security Token Service (STS), uses the provided
     * {@link #roleArn} to assume a role and then request short lived session
     * credentials, which will then be returned by this class's
     * {@link #getCredentials()} method.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     * @param clientConfiguration
     *            The AWS ClientConfiguration to use when making AWS API requests.
     */
    public STSAssumeRoleSessionCredentialsProvider(String roleArn, ClientConfiguration clientConfiguration) {
        this.roleArn = roleArn;
        securityTokenService = new AWSSecurityTokenServiceClient(clientConfiguration);
    }

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which will use
     * the specified long lived AWS credentials to make a request to the AWS
     * Security Token Service (STS), uses the provided {@link #roleArn} to
     * assume a role and then request short lived session credentials, which
     * will then be returned by this class's {@link #getCredentials()} method.
     * @param longLivedCredentials
     *            The main AWS credentials for a user's account.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     */
    public STSAssumeRoleSessionCredentialsProvider(AWSCredentials longLivedCredentials, String roleArn) {
        this(longLivedCredentials, roleArn, new ClientConfiguration());
    }

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which will use
     * the specified long lived AWS credentials to make a request to the AWS
     * Security Token Service (STS), uses the provided {@link #roleArn} to
     * assume a role and then request short lived session credentials, which
     * will then be returned by this class's {@link #getCredentials()} method.
     * @param longLivedCredentials
     *            The main AWS credentials for a user's account.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     * @param clientConfiguration
     *            Client configuration connection parameters.
     */
    public STSAssumeRoleSessionCredentialsProvider(AWSCredentials longLivedCredentials, String roleArn,
            ClientConfiguration clientConfiguration) {
        this.roleArn = roleArn;
        securityTokenService = new AWSSecurityTokenServiceClient(longLivedCredentials, clientConfiguration);
    }

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which will use
     * the specified credentials provider (which vends long lived AWS
     * credentials) to make a request to the AWS Security Token Service (STS),
     * usess the provided {@link #roleArn} to assume a role and then request
     * short lived session credentials, which will then be returned by this
     * class's {@link #getCredentials()} method.
     * @param longLivedCredentialsProvider
     *            Credentials provider for the main AWS credentials for a user's
     *            account.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     */
    public STSAssumeRoleSessionCredentialsProvider(AWSCredentialsProvider longLivedCredentialsProvider,
            String roleArn) {
        this.roleArn = roleArn;
        securityTokenService = new AWSSecurityTokenServiceClient(longLivedCredentialsProvider);
    }

    /**
     * Constructs a new STSAssumeRoleSessionCredentialsProvider, which will use
     * the specified credentials provider (which vends long lived AWS
     * credentials) to make a request to the AWS Security Token Service (STS),
     * uses the provided {@link #roleArn} to assume a role and then request
     * short lived session credentials, which will then be returned by this
     * class's {@link #getCredentials()} method.
     * @param longLivedCredentialsProvider
     *            Credentials provider for the main AWS credentials for a user's
     *            account.
     * @param roleArn
     *            The AWS ARN of the Role to be assumed.
     * @param clientConfiguration
     *            Client configuration connection parameters.
     */
    public STSAssumeRoleSessionCredentialsProvider(AWSCredentialsProvider longLivedCredentialsProvider, String roleArn,
            ClientConfiguration clientConfiguration) {
        this.roleArn = roleArn;
        securityTokenService = new AWSSecurityTokenServiceClient(longLivedCredentialsProvider, clientConfiguration);
    }

    @Override
    public AWSCredentials getCredentials() {
        if (needsNewSession()) {
            startSession();
        }
        return sessionCredentials;
    }

    @Override
    public void refresh() {
        startSession();
    }

    /**
     * Starts a new session by sending a request to the AWS Security Token
     * Service (STS) to assume a Role using the long lived AWS credentials. This
     * class then vends the short lived session credentials for the assumed Role
     * sent back from STS.
     */
    private void startSession() {
        AssumeRoleResult assumeRoleResult = securityTokenService.assumeRole(new AssumeRoleRequest()
                .withRoleArn(roleArn).withDurationSeconds(DEFAULT_DURATION_SECONDS).withRoleSessionName("SimianArmy"));
        Credentials stsCredentials = assumeRoleResult.getCredentials();
        sessionCredentials = new BasicSessionCredentials(stsCredentials.getAccessKeyId(),
                stsCredentials.getSecretAccessKey(), stsCredentials.getSessionToken());
        sessionCredentialsExpiration = stsCredentials.getExpiration();
    }

    /**
     * Returns true if a new STS session needs to be started. A new STS session
     * is needed when no session has been started yet, or if the last session is
     * within {@link #EXPIRY_TIME_MILLIS} seconds of expiring.
     * @return True if a new STS session needs to be started.
     */
    private boolean needsNewSession() {
        if (sessionCredentials == null) {
            return true;
        }
        long timeRemaining = sessionCredentialsExpiration.getTime() - System.currentTimeMillis();
        return timeRemaining < EXPIRY_TIME_MILLIS;
    }

}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/SimpleDBRecorder.java
================================================
/*
 *
 *  Copyright 2012 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.AmazonClientException;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.ListDomainsResult;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.amazonaws.services.simpledb.model.SelectResult;
import com.netflix.simianarmy.EventType;
import com.netflix.simianarmy.MonkeyRecorder;
import com.netflix.simianarmy.MonkeyType;
import com.netflix.simianarmy.NamedType;
import com.netflix.simianarmy.basic.BasicRecorderEvent;
import com.netflix.simianarmy.client.aws.AWSClient;

/**
 * The Class SimpleDBRecorder. Records events to and fetched events from a Amazon SimpleDB table (default SIMIAN_ARMY)
 */
@SuppressWarnings("serial")
public class SimpleDBRecorder implements MonkeyRecorder {
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDBRecorder.class);

    private final AmazonSimpleDB simpleDBClient;

    private final String region;

    /** The domain. */
    private final String domain;

    /**
     * The Enum Keys.
     */
    private enum Keys {

        /** The event id. */
        id,
        /** The event time. */
        eventTime,
        /** The region. */
        region,
        /** The record type. */
        recordType,
        /** The monkey type. */
        monkeyType,
        /** The event type. */
        eventType;

        /** The Constant KEYSET. */
        public static final Set<String> KEYSET = Collections.unmodifiableSet(new HashSet<String>() {
            {
                for (Keys k : Keys.values()) {
                    add(k.toString());
                }
            }
        });
    };

    /**
     * Instantiates a new simple db recorder.
     *
     * @param awsClient
     *            the AWS client
     * @param domain
     *            the domain
     */
    public SimpleDBRecorder(AWSClient awsClient, String domain) {
        Validate.notNull(awsClient);
        Validate.notNull(domain);
        this.simpleDBClient = awsClient.sdbClient();
        this.region = awsClient.region();
        this.domain = domain;
    }

    /**
     * simple client. abstracted to aid testing
     *
     * @return the amazon simple db
     */
    protected AmazonSimpleDB sdbClient() {
        return simpleDBClient;
    }

    /**
     * Enum to value. Converts an enum to "name|type" string
     *
     * @param e
     *            the e
     * @return the string
     */
    public static String enumToValue(NamedType e) {
        return String.format("%s|%s", e.name(), e.getClass().getName());
    }

    /**
     * Value to enum. Converts a "name|type" string back to an enum.
     *
     * @param value
     *            the value
     * @return the enum
     */
    public static <T extends NamedType> T valueToEnum(
            Class<T> type, String value) {
        // parts = [enum value, enum class type]
        String[] parts = value.split("\\|", 2);
        if (parts.length < 2) {
            throw new RuntimeException("value " + value + " does not appear to be an internal enum format");
        }

        Class<?> enumClass;
        try {
            enumClass = Class.forName(parts[1]);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("class for enum value " + value + " not found");
        }
        if (!enumClass.isEnum()) {
            throw new RuntimeException("value " + value + " does not appear to be of an enum type");
        }
        if (!type.isAssignableFrom(enumClass)) {
            throw new RuntimeException("value " + value + " cannot be assigned to a variable of this type: "
                    + type.getCanonicalName());
        }
        @SuppressWarnings("rawtypes")
        Class<? extends Enum> enumType = enumClass.asSubclass(Enum.class);
        @SuppressWarnings("unchecked")
        T enumValue = (T) Enum.valueOf(enumType, parts[0]);
        return enumValue;
    }

    /** {@inheritDoc} */
    @Override
    public Event newEvent(MonkeyType monkeyType, EventType eventType, String reg, String id) {
        return new BasicRecorderEvent(monkeyType, eventType, reg, id);
    }

    /** {@inheritDoc} */
    @Override
    public void recordEvent(Event evt) {
        String evtTime = String.valueOf(evt.eventTime().getTime());
        List<ReplaceableAttribute> attrs = new LinkedList<ReplaceableAttribute>();
        attrs.add(new ReplaceableAttribute(Keys.id.name(), evt.id(), true));
        attrs.add(new ReplaceableAttribute(Keys.eventTime.name(), evtTime, true));
        attrs.add(new ReplaceableAttribute(Keys.region.name(), evt.region(), true));
        attrs.add(new ReplaceableAttribute(Keys.recordType.name(), "MonkeyEvent", true));
        attrs.add(new ReplaceableAttribute(Keys.monkeyType.name(), enumToValue(evt.monkeyType()), true));
        attrs.add(new ReplaceableAttribute(Keys.eventType.name(), enumToValue(evt.eventType()), true));
        for (Map.Entry<String, String> pair : evt.fields().entrySet()) {
            if (pair.getValue() == null || pair.getValue().equals("") || Keys.KEYSET.contains(pair.getKey())) {
                continue;
            }
            attrs.add(new ReplaceableAttribute(pair.getKey(), pair.getValue(), true));
        }
        // Let pk contain the timestamp so that the same resource can have multiple events.
        String pk = String.format("%s-%s-%s-%s", evt.monkeyType().name(), evt.id(), region, evtTime);
        PutAttributesRequest putReq = new PutAttributesRequest(domain, pk, attrs);
        sdbClient().putAttributes(putReq);

    }

    /**
     * Find events.
     *
     * @param queryMap
     *            the query map
     * @param after
     *            the start time to query for all events after
     * @return the list
     */
    protected List<Event> findEvents(Map<String, String> queryMap, long after) {
        StringBuilder query = new StringBuilder(
                String.format("select * from `%s` where region = '%s'", domain, region));
        for (Map.Entry<String, String> pair : queryMap.entrySet()) {
            query.append(String.format(" and %s = '%s'", pair.getKey(), pair.getValue()));
        }
        query.append(String.format(" and eventTime > '%d'", after));
        // always return with most recent record first
        query.append(" order by eventTime desc");

        List<Event> list = new LinkedList<Event>();
        SelectRequest request = new SelectRequest(query.toString());
        request.setConsistentRead(Boolean.TRUE);

        SelectResult result = new SelectResult();
        do {
            result = sdbClient().select(request.withNextToken(result.getNextToken()));
            for (Item item : result.getItems()) {
                Map<String, String> fields = new HashMap<String, String>();
                Map<String, String> res = new HashMap<String, String>();
                for (Attribute attr : item.getAttributes()) {
                    if (Keys.KEYSET.contains(attr.getName())) {
                        res.put(attr.getName(), attr.getValue());
                    } else {
                        fields.put(attr.getName(), attr.getValue());
                    }
                }
                String eid = res.get(Keys.id.name());
                String ereg = res.get(Keys.region.name());
                MonkeyType monkeyType = valueToEnum(MonkeyType.class, res.get(Keys.monkeyType.name()));
                EventType eventType = valueToEnum(EventType.class, res.get(Keys.eventType.name()));
                long eventTime = Long.parseLong(res.get(Keys.eventTime.name()));
                list.add(new BasicRecorderEvent(monkeyType, eventType, ereg, eid, eventTime).addFields(fields));
            }
        } while (result.getNextToken() != null);
        return list;
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(Map<String, String> query, Date after) {
        return findEvents(query, after.getTime());
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(MonkeyType monkeyType, Map<String, String> query, Date after) {
        Map<String, String> copy = new LinkedHashMap<String, String>(query);
        copy.put(Keys.monkeyType.name(), enumToValue(monkeyType));
        return findEvents(copy, after);
    }

    /** {@inheritDoc} */
    @Override
    public List<Event> findEvents(MonkeyType monkeyType, EventType eventType, Map<String, String> query, Date after) {
        Map<String, String> copy = new LinkedHashMap<String, String>(query);
        copy.put(Keys.monkeyType.name(), enumToValue(monkeyType));
        copy.put(Keys.eventType.name(), enumToValue(eventType));
        return findEvents(copy, after);
    }

    /**
     * Creates the SimpleDB domain, if it does not already exist.
     */
    public void init() {
        try {
            if (this.region == null || this.region.equals("region-null")) {
                // This is a mock with an invalid region; avoid a slow timeout
                LOGGER.debug("Region=null; skipping SimpleDB domain creation");
                return;
            }
            ListDomainsResult listDomains = sdbClient().listDomains();
            for (String d : listDomains.getDomainNames()) {
                if (d.equals(domain)) {
                    LOGGER.debug("SimpleDB domain found: {}", domain);
                    return;
                }
            }
            LOGGER.info("Creating SimpleDB domain: {}", domain);
            CreateDomainRequest createDomainRequest = new CreateDomainRequest(
                    domain);
            sdbClient().createDomain(createDomainRequest);
        } catch (AmazonClientException e) {
            LOGGER.warn("Error while trying to auto-create SimpleDB domain", e);
        }
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/conformity/RDSConformityClusterTracker.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws.conformity;

import com.amazonaws.AmazonClientException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.simianarmy.aws.AWSResource;
import com.netflix.simianarmy.conformity.Cluster;
import com.netflix.simianarmy.conformity.Conformity;
import com.netflix.simianarmy.conformity.ConformityClusterTracker;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The RDSConformityClusterTracker implementation in RDS (relational database).
 */
public class RDSConformityClusterTracker implements ConformityClusterTracker {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(RDSConformityClusterTracker.class);

    /** The table. */
    private final String table;
    
    /** the jdbcTemplate  */
    JdbcTemplate jdbcTemplate = null;
    
    /**
     * Instantiates a new RDS db resource tracker.
     *
     */
    public RDSConformityClusterTracker(String dbDriver, String dbUser,
			String dbPass, String dbUrl, String dbTable) {
		HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(dbDriver);
		dataSource.setJdbcUrl(dbUrl);
		dataSource.setUsername(dbUser);
		dataSource.setPassword(dbPass);
		dataSource.setMaximumPoolSize(2);
    	this.jdbcTemplate = new JdbcTemplate(dataSource);
    	this.table = dbTable;
	}

    /**
     * Instantiates a new RDS conformity cluster tracker.  This constructor is intended
     * for unit testing.
     *
     */
    public RDSConformityClusterTracker(JdbcTemplate jdbcTemplate, String table) {
    	this.jdbcTemplate = jdbcTemplate;
    	this.table = table;
    }
    
    public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

    public Object value(String value) {
    	return value == null ? Types.NULL : value;
    }

    public Object value(Date value) {
    	return value == null ? Types.NULL : value.getTime();
    }    

    public Object value(boolean value) {
    	return Boolean.toString(value);
    }

	public Object emailValue(String email) {
		if (StringUtils.isBlank(email)) return Types.NULL;
		if (email.equals("0")) return Types.NULL;
		return email;
	}

    /** {@inheritDoc} */
    @Override
    public void addOrUpdate(Cluster cluster) {
    	Cluster orig = getCluster(cluster.getName(), cluster.getRegion());    	
        LOGGER.debug(String.format("Saving cluster %s to RDB table %s in region %s", cluster.getName(), cluster.getRegion(), table));
		Map<String, String> map = cluster.getFieldToValueMap();

    	String conformityJson;
		try {
			conformityJson = new ObjectMapper().writeValueAsString(conformitiesAsMap(cluster));
		} catch (JsonProcessingException e) {
			LOGGER.error("ERROR generating conformities JSON when saving cluster " + cluster.getName() + ", " + cluster.getRegion(), e);
			return;
		}
		
    	if (orig == null) {
    		StringBuilder sb = new StringBuilder();
    		sb.append("insert into ").append(table);
    		sb.append(" (");
    		sb.append(Cluster.CLUSTER).append(",");
    		sb.append(Cluster.REGION).append(",");
    		sb.append(Cluster.OWNER_EMAIL).append(",");
    		sb.append(Cluster.IS_CONFORMING).append(",");
    		sb.append(Cluster.IS_OPTEDOUT).append(",");
    		sb.append(Cluster.UPDATE_TIMESTAMP).append(",");
    		sb.append(Cluster.EXCLUDED_RULES).append(",");
    		sb.append("conformities").append(",");
    		sb.append(Cluster.CONFORMITY_RULES);
    		sb.append(") values (?,?,?,?,?,?,?,?,?)");

            LOGGER.debug(String.format("Insert statement is '%s'", sb));
    		this.jdbcTemplate.update(sb.toString(),
    								 value(map.get(Cluster.CLUSTER)),
    								 value(map.get(Cluster.REGION)),
									 emailValue(map.get(Cluster.OWNER_EMAIL)),
    								 value(map.get(Cluster.IS_CONFORMING)),
    								 value(map.get(Cluster.IS_OPTEDOUT)),
    								 value(cluster.getUpdateTime()),
    								 value(map.get(Cluster.EXCLUDED_RULES)),
    								 value(conformityJson),
    								 value(map.get(Cluster.CONFORMITY_RULES)));
    	} else {
    		StringBuilder sb = new StringBuilder();
    		sb.append("update ").append(table).append(" set ");
    		sb.append(Cluster.OWNER_EMAIL).append("=?,");
    		sb.append(Cluster.IS_CONFORMING).append("=?,");
    		sb.append(Cluster.IS_OPTEDOUT).append("=?,");
    		sb.append(Cluster.UPDATE_TIMESTAMP).append("=?,");
    		sb.append(Cluster.EXCLUDED_RULES).append("=?,");
    		sb.append("conformities").append("=?,");
    		sb.append(Cluster.CONFORMITY_RULES).append("=? where ");
    		sb.append(Cluster.CLUSTER).append("=? and ");
    		sb.append(Cluster.REGION).append("=?");

            LOGGER.debug(String.format("Update statement is '%s'", sb));
    		this.jdbcTemplate.update(sb.toString(),
    								emailValue(map.get(Cluster.OWNER_EMAIL)),
    								value(map.get(Cluster.IS_CONFORMING)),
    								value(map.get(Cluster.IS_OPTEDOUT)),
    								value(cluster.getUpdateTime()),
    								value(map.get(Cluster.EXCLUDED_RULES)),
    								value(conformityJson),
    								value(map.get(Cluster.CONFORMITY_RULES)),
    								value(cluster.getName()),
									value(cluster.getRegion()));    	
    	}
    	LOGGER.debug("Successfully saved.");
    }

    private HashMap<String,String> conformitiesAsMap(Cluster cluster) {
    	HashMap<String,String> map = new HashMap<>();
    	
    	for(Conformity conformity : cluster.getConformties()) {
            map.put(conformity.getRuleId(), StringUtils.join(conformity.getFailedComponents(), ","));
    	}
    	
		return map;
	}
    
	/**
     * Gets the clusters for a list of regions. If the regions parameter is empty, returns the clusters
     * for all regions.
     */
    @Override
    public List<Cluster> getAllClusters(String... regions) {
        return getClusters(null, regions);
    }

    @Override
    public List<Cluster> getNonconformingClusters(String... regions) {
        return getClusters(false, regions);
    }

    @Override
    public Cluster getCluster(String clusterName, String region) {
        Validate.notEmpty(clusterName);
        Validate.notEmpty(region);
        StringBuilder query = new StringBuilder();
        query.append(String.format("select * from %s where cluster = ? and region = ?", table));
        LOGGER.info(String.format("Query is '%s'", query));

        List<Cluster> clusters = jdbcTemplate.query(query.toString(), new String[] {clusterName, region}, new RowMapper<Cluster>() {
            public Cluster mapRow(ResultSet rs, int rowNum) throws SQLException {
            	return mapResource(rs);                
            }             
        });                
        Validate.isTrue(clusters.size() <= 1);
        if (clusters.size() == 0) {
            LOGGER.info(String.format("Not found cluster with name %s in region %s", clusterName, region));
            return null;
        } else {
            Cluster cluster = clusters.get(0);
            return cluster;
        }
    }
    
    private Cluster mapResource(ResultSet rs) throws SQLException {
    	Map<String, String> map = conformityMapFromJson(rs.getString("conformities"));
		map.put(Cluster.CLUSTER, rs.getString(Cluster.CLUSTER));
		map.put(Cluster.REGION, rs.getString(Cluster.REGION));
		map.put(Cluster.IS_CONFORMING, rs.getString(Cluster.IS_CONFORMING));
		map.put(Cluster.IS_OPTEDOUT, rs.getString(Cluster.IS_OPTEDOUT));

		String email = rs.getString(Cluster.OWNER_EMAIL);
		if (StringUtils.isBlank(email) || email.equals("0")) {
			email = null;
		}
		map.put(Cluster.OWNER_EMAIL, email);

		String updatedTimestamp = millisToFormattedDate(rs.getString(Cluster.UPDATE_TIMESTAMP));
		if (updatedTimestamp != null) {
			map.put(Cluster.UPDATE_TIMESTAMP, updatedTimestamp);
		}
		
		map.put(Cluster.EXCLUDED_RULES, rs.getString(Cluster.EXCLUDED_RULES));
		map.put(Cluster.CONFORMITY_RULES, rs.getString(Cluster.CONFORMITY_RULES));
		return Cluster.parseFieldToValueMap(map);
    }                 
    
    private String millisToFormattedDate(String millisStr) {
    	String datetime = null;
    	try {
    		long millis = Long.parseLong(millisStr);
    		datetime = AWSResource.DATE_FORMATTER.print(millis);
    	} catch(NumberFormatException nfe) {
			LOGGER.error(String.format("Error parsing datetime %s when reading from RDS", millisStr));
    	}
    	return datetime;
    }
    
    private HashMap<String,String> conformityMapFromJson(String json) throws SQLException {
    	HashMap<String,String> map = new HashMap<>();
    	
    	if (json != null) {	    	
	    	TypeReference<HashMap<String,String>> typeRef = new TypeReference<HashMap<String,String>>() {};
	    	
	    	try {
	        	ObjectMapper mapper = new ObjectMapper();
	    		map = mapper.readValue(json, typeRef);
	    	}catch(IOException ie) {
	    		String msg = "Error parsing conformities from result set";
	    		LOGGER.error(msg, ie);
	    		throw new SQLException(msg);    		
	    	}    	
    	}
		return map;
	}

	@Override
    public void deleteClusters(Cluster... clusters) {
        Validate.notNull(clusters);
        LOGGER.info(String.format("Deleting %d clusters", clusters.length));
        for (Cluster cluster : clusters) {
            LOGGER.info(String.format("Deleting cluster %s", cluster.getName()));
            String stmt = String.format("delete from %s where %s=? and %s=?", table, Cluster.CLUSTER, Cluster.REGION);
            jdbcTemplate.update(stmt, cluster.getName(), cluster.getRegion());
            LOGGER.info(String.format("Successfully deleted cluster %s", cluster.getName()));
        }
    }

    private List<Cluster> getClusters(Boolean conforming, String... regions) {
        Validate.notNull(regions);
        StringBuilder query = new StringBuilder();
        query.append(String.format("select * from %s where cluster is not null and ", table));
        boolean needsAnd = false;
        if (regions.length != 0) {
            query.append(String.format("region in ('%s') ", StringUtils.join(regions, "','")));
            needsAnd = true;
        }
        if (conforming != null) {
            if (needsAnd) {
                query.append(" and ");
            }
            query.append(String.format("isConforming = '%s'", conforming));
        }

        LOGGER.info(String.format("Query to retrieve clusters for regions %s is '%s'",
                StringUtils.join(regions, "','"), query.toString()));

        List<Cluster> clusters = jdbcTemplate.query(query.toString(), new RowMapper<Cluster>() {
            public Cluster mapRow(ResultSet rs, int rowNum) throws SQLException {
            	return mapResource(rs);                
            }             
        });                
        
        LOGGER.info(String.format("Retrieved %d clusters from RDS DB in table %s and regions %s",
                clusters.size(), table, StringUtils.join(regions, "','")));
        return clusters;
    }
    
    /**
     * Creates the RDS table, if it does not already exist.
     */
    public void init() {
        try {
            LOGGER.info("Creating RDS table: {}", table);
            String sql = String.format("create table if not exists %s ("
                                     + " %s varchar(255),"
                                     + " %s varchar(25),"
                                     + " %s varchar(255),"
                                     + " %s varchar(10),"
                                     + " %s varchar(10),"
                                     + " %s BIGINT," 
                                     + " %s varchar(4096),"
                                     + " %s varchar(4096),"
                                     + " %s varchar(4096) )",
                                     table,
                                     Cluster.CLUSTER,
                                     Cluster.REGION,
                                     Cluster.OWNER_EMAIL,
                                     Cluster.IS_CONFORMING,
                                     Cluster.IS_OPTEDOUT,
                                     Cluster.UPDATE_TIMESTAMP,
                                     Cluster.EXCLUDED_RULES,
                                     "conformities",
                                     Cluster.CONFORMITY_RULES);
           LOGGER.debug("Create SQL is: '{}'", sql);
           jdbcTemplate.execute(sql);
            
        } catch (AmazonClientException e) {
            LOGGER.warn("Error while trying to auto-create RDS table", e);
        }
    }    
}

================================================
FILE: src/main/java/com/netflix/simianarmy/aws/conformity/SimpleDBConformityClusterTracker.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws.conformity;

import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.amazonaws.services.simpledb.model.SelectResult;
import com.google.common.collect.Lists;
import com.netflix.simianarmy.client.aws.AWSClient;
import com.netflix.simianarmy.conformity.Cluster;
import com.netflix.simianarmy.conformity.ConformityClusterTracker;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The ConformityResourceTracker implementation in SimpleDB.
 */
public class SimpleDBConformityClusterTracker implements ConformityClusterTracker {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDBConformityClusterTracker.class);

    /** The domain. */
    private final String domain;

    /** The SimpleDB client. */
    private final AmazonSimpleDB simpleDBClient;

    private static final int  MAX_ATTR_SIZE = 1024;

    /**
     * Instantiates a new simple db cluster tracker for conformity monkey.
     *
     * @param awsClient
     *            the AWS Client
     * @param domain
     *            the domain
     */
    public SimpleDBConformityClusterTracker(AWSClient awsClient, String domain) {
        Validate.notNull(awsClient);
        Validate.notNull(domain);
        this.domain = domain;
        this.simpleDBClient = awsClient.sdbClient();
    }

    /**
     * Gets the SimpleDB client.
     * @return the SimpleDB client
     */
    protected AmazonSimpleDB getSimpleDBClient() {
        return simpleDBClient;
    }

    /** {@inheritDoc} */
    @Override
    public void addOrUpdate(Cluster cluster) {
        List<ReplaceableAttribute> attrs = new ArrayList<ReplaceableAttribute>();
        Map<String, String> fieldToValueMap = cluster.getFieldToValueMap();
        for (Map.Entry<String, String> entry : fieldToValueMap.entrySet()) {
            attrs.add(new ReplaceableAttribute(entry.getKey(), StringUtils.left(entry.getValue(), MAX_ATTR_SIZE),
                    true));
        }
        PutAttributesRequest putReqest = new PutAttributesRequest(domain, getSimpleDBItemName(cluster), attrs);
        LOGGER.debug(String.format("Saving cluster %s to SimpleDB domain %s",
                cluster.getName(), domain));
        this.simpleDBClient.putAttributes(putReqest);
        LOGGER.debug("Successfully saved.");
    }



    /**
     * Gets the clusters for a list of regions. If the regions parameter is empty, returns the clusters
     * for all regions.
     */
    @Override
    public List<Cluster> getAllClusters(String... regions) {
        return getClusters(null, regions);
    }

    @Override
    public List<Cluster> getNonconformingClusters(String... regions) {
        return getClusters(false, regions);
    }

    @Override
    public Cluster getCluster(String clusterName, String region) {
        Validate.notEmpty(clusterName);
        Validate.notEmpty(region);
        StringBuilder query = new StringBuilder();
        query.append(String.format("select * from `%s` where cluster = '%s' and region = '%s'",
                domain, clusterName, region));

        LOGGER.info(String.format("Query is to get the cluster is '%s'", query));

        List<Item> items = querySimpleDBItems(query.toString());
        Validate.isTrue(items.size() <= 1);
        if (items.size() == 0) {
            LOGGER.info(String.format("Not found cluster with name %s in region %s", clusterName, region));
            return null;
        } else {
            Cluster cluster = null;
            try {
                cluster = parseCluster(items.get(0));
            } catch (Exception e) {
                // Ignore the item that cannot be parsed.
                LOGGER.error(String.format("SimpleDB item %s cannot be parsed into a cluster.", items.get(0)));
            }
            return cluster;
        }
    }

    @Override
    public void deleteClusters(Cluster... clusters) {
        Validate.notNull(clusters);
        LOGGER.info(String.format("Deleting %d clusters", clusters.length));
        for (Cluster cluster : clusters) {
            LOGGER.info(String.format("Deleting cluster %s", cluster.getName()));
            simpleDBClient.deleteAttributes(new DeleteAttributesRequest(domain, getSimpleDBItemName(cluster)));
            LOGGER.info(String.format("Successfully deleted cluster %s", cluster.getName()));
        }
    }

    private List<Cluster> getClusters(Boolean conforming, String... regions) {
        Validate.notNull(regions);
        List<Cluster> clusters = Lists.newArrayList();
        StringBuilder query = new StringBuilder();
        query.append(String.format("select * from `%s` where cluster is not null and ", domain));
        boolean needsAnd = false;
        if (regions.length != 0) {
            query.append(String.format("region in ('%s') ", StringUtils.join(regions, "','")));
            needsAnd = true;
        }
        if (conforming != null) {
            if (needsAnd) {
                query.append(" and ");
            }
            query.append(String.format("isConforming = '%s'", conforming));
        }

        LOGGER.info(String.format("Query to retrieve clusters for regions %s is '%s'",
                StringUtils.join(regions, "','"), query.toString()));

        List<Item> items = querySimpleDBItems(query.toString());
        for (Item item : items) {
            try {
                clusters.add(parseCluster(item));
            } catch (Exception e) {
                // Ignore the item that cannot be parsed.
                LOGGER.error(String.format("SimpleDB item %s cannot be parsed into a cluster.", item), e);
            }
        }
        LOGGER.info(String.format("Retrieved %d clusters from SimpleDB in domain %s and regions %s",
                clusters.size(), domain, StringUtils.join(regions, "','")));
        return clusters;
    }

    /**
     * Parses a SimpleDB item into a cluster.
     * @param item the item from SimpleDB
     * @return the cluster for the SimpleDB item
     */
    protected Cluster parseCluster(Item item) {
        Map<String, String> fieldToValue = new HashMap<String, String>();
        for (Attribute attr : item.getAttributes()) {
            String name = attr.getName();
            String value = attr.getValue();
            if (name != null && value != null) {
                fieldToValue.put(name, value);
            }
        }
        return Cluster.parseFieldToValueMap(fieldToValue);
    }

    /**
     * Gets the unique SimpleDB item name for a cluster. The subclass can override this
     * method to generate the item name differently.
     * @param cluster
     * @return the SimpleDB item name for the cluster
     */
    protected String getSimpleDBItemName(Cluster cluster) {
        return String.format("%s-%s", cluster.getName(), cluster.getRegion());
    }

    private List<Item> querySimpleDBItems(String query) {
        Validate.notNull(query);
        String nextToken = null;
        List<Item> items = new ArrayList<Item>();
        do {
            SelectRequest request = new SelectRequest(query);
            request.setNextToken(nextToken);
            request.setConsistentRead(Boolean.TRUE);
            SelectResult result = this.simpleDBClient.select(request);
            items.addAll(result.getItems());
            nextToken = result.getNextToken();
        } while (nextToken != null);

        return items;
    }
}


================================================
FILE: src/main/java/com/netflix/simianarmy/aws/conformity/crawler/AWSClusterCrawler.java
================================================
/*
 *
 *  Copyright 2013 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.simianarmy.aws.conformity.crawler;

import com.amazonaws.services.autoscaling.model.AutoScalingGroup;
import com.amazonaws.services.autoscaling.model.TagDescription;
import com.amazonaws.services.autoscaling.model.Instance;
import com.amazonaws.services.autoscaling.model.SuspendedProcess;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.netflix.simianarmy.basic.BasicSimianArmyContext;
import com.netflix.simianarmy.MonkeyConfiguration;
import com.netflix.simianarmy.client.aws.AWSClient;
import com.netflix.simianarmy.conformity.Cluster;
import com.netflix.simianarmy.conformity.ClusterCrawler;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * The class implementing a crawler that gets the auto scaling groups from AWS.
 */
public class AWSClusterCrawler implements ClusterCrawler {
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(AWSClusterCrawler.class);

    private static final String NS = "simianarmy.conformity.cluster";

    /** The map from region to the aws client in the region. */
    private final Map<String, AWSClient> regionToAwsClient = Maps.newHashMap();

    private final MonkeyConfiguration cfg;

    /**
     * Instantiates a new cluster crawler.
     *
     * @param regionToAwsClient
     *            the map from region to the corresponding aws client for the region
     */
    public AWSClusterCrawler(Map<String, AWSClient> regionToAwsClient, MonkeyConfiguration cfg) {
        Validate.notNull(regionToAwsClient);
        Validate.notNull(cfg);
        for (Map.Entry<String, AWSClient> entry : regionToAwsClient.entrySet()) {
            this.regionToAwsClient.put(entry.getKey(), entry.getValue());
        }
        this.cfg = cfg;
    }

    /**
     * In this implementation, every auto scaling group is considered a cluster.
     * @param clusterNames
     *          the cluster names
     * @return the list of clusters matching the na
Download .txt
gitextract_54dtl7c9/

├── .gitignore
├── .netflixoss
├── .travis.yml
├── CHANGELOG.md
├── GNUmakefile
├── LICENSE
├── OSSMETADATA
├── README.md
├── build.gradle
├── buildViaTravis.sh
├── codequality/
│   ├── checkstyle.xml
│   └── org.eclipse.jdt.core.prefs
├── gradle/
│   └── wrapper/
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── installViaTravis.sh
├── settings.gradle
└── src/
    ├── main/
    │   ├── java/
    │   │   └── com/
    │   │       └── netflix/
    │   │           └── simianarmy/
    │   │               ├── AbstractEmailBuilder.java
    │   │               ├── CloudClient.java
    │   │               ├── EmailBuilder.java
    │   │               ├── EventType.java
    │   │               ├── FeatureNotEnabledException.java
    │   │               ├── GroupType.java
    │   │               ├── InstanceGroupNotFoundException.java
    │   │               ├── Monkey.java
    │   │               ├── MonkeyCalendar.java
    │   │               ├── MonkeyConfiguration.java
    │   │               ├── MonkeyEmailNotifier.java
    │   │               ├── MonkeyRecorder.java
    │   │               ├── MonkeyRunner.java
    │   │               ├── MonkeyScheduler.java
    │   │               ├── MonkeyType.java
    │   │               ├── NamedType.java
    │   │               ├── NotFoundException.java
    │   │               ├── Resource.java
    │   │               ├── ResourceType.java
    │   │               ├── aws/
    │   │               │   ├── AWSEmailNotifier.java
    │   │               │   ├── AWSResource.java
    │   │               │   ├── AWSResourceType.java
    │   │               │   ├── RDSRecorder.java
    │   │               │   ├── STSAssumeRoleSessionCredentialsProvider.java
    │   │               │   ├── SimpleDBRecorder.java
    │   │               │   ├── conformity/
    │   │               │   │   ├── RDSConformityClusterTracker.java
    │   │               │   │   ├── SimpleDBConformityClusterTracker.java
    │   │               │   │   ├── crawler/
    │   │               │   │   │   └── AWSClusterCrawler.java
    │   │               │   │   └── rule/
    │   │               │   │       ├── BasicConformityEurekaClient.java
    │   │               │   │       ├── ConformityEurekaClient.java
    │   │               │   │       ├── CrossZoneLoadBalancing.java
    │   │               │   │       ├── InstanceHasHealthCheckUrl.java
    │   │               │   │       ├── InstanceHasStatusUrl.java
    │   │               │   │       ├── InstanceInSecurityGroup.java
    │   │               │   │       ├── InstanceInVPC.java
    │   │               │   │       ├── InstanceIsHealthyInEureka.java
    │   │               │   │       ├── InstanceTooOld.java
    │   │               │   │       └── SameZonesInElbAndAsg.java
    │   │               │   └── janitor/
    │   │               │       ├── ASGJanitor.java
    │   │               │       ├── EBSSnapshotJanitor.java
    │   │               │       ├── EBSVolumeJanitor.java
    │   │               │       ├── ELBJanitor.java
    │   │               │       ├── ImageJanitor.java
    │   │               │       ├── InstanceJanitor.java
    │   │               │       ├── LaunchConfigJanitor.java
    │   │               │       ├── RDSJanitorResourceTracker.java
    │   │               │       ├── SimpleDBJanitorResourceTracker.java
    │   │               │       ├── VolumeTaggingMonkey.java
    │   │               │       ├── crawler/
    │   │               │       │   ├── ASGJanitorCrawler.java
    │   │               │       │   ├── AbstractAWSJanitorCrawler.java
    │   │               │       │   ├── EBSSnapshotJanitorCrawler.java
    │   │               │       │   ├── EBSVolumeJanitorCrawler.java
    │   │               │       │   ├── ELBJanitorCrawler.java
    │   │               │       │   ├── InstanceJanitorCrawler.java
    │   │               │       │   ├── LaunchConfigJanitorCrawler.java
    │   │               │       │   └── edda/
    │   │               │       │       ├── EddaASGJanitorCrawler.java
    │   │               │       │       ├── EddaEBSSnapshotJanitorCrawler.java
    │   │               │       │       ├── EddaEBSVolumeJanitorCrawler.java
    │   │               │       │       ├── EddaELBJanitorCrawler.java
    │   │               │       │       ├── EddaImageJanitorCrawler.java
    │   │               │       │       ├── EddaInstanceJanitorCrawler.java
    │   │               │       │       ├── EddaLaunchConfigJanitorCrawler.java
    │   │               │       │       └── EddaUtils.java
    │   │               │       └── rule/
    │   │               │           ├── ami/
    │   │               │           │   └── UnusedImageRule.java
    │   │               │           ├── asg/
    │   │               │           │   ├── ASGInstanceValidator.java
    │   │               │           │   ├── DiscoveryASGInstanceValidator.java
    │   │               │           │   ├── DummyASGInstanceValidator.java
    │   │               │           │   ├── OldEmptyASGRule.java
    │   │               │           │   └── SuspendedASGRule.java
    │   │               │           ├── elb/
    │   │               │           │   └── OrphanedELBRule.java
    │   │               │           ├── generic/
    │   │               │           │   ├── TagValueExclusionRule.java
    │   │               │           │   └── UntaggedRule.java
    │   │               │           ├── instance/
    │   │               │           │   └── OrphanedInstanceRule.java
    │   │               │           ├── launchconfig/
    │   │               │           │   └── OldUnusedLaunchConfigRule.java
    │   │               │           ├── snapshot/
    │   │               │           │   └── NoGeneratedAMIRule.java
    │   │               │           └── volume/
    │   │               │               ├── DeleteOnTerminationRule.java
    │   │               │               └── OldDetachedVolumeRule.java
    │   │               ├── basic/
    │   │               │   ├── BasicCalendar.java
    │   │               │   ├── BasicChaosMonkeyContext.java
    │   │               │   ├── BasicConfiguration.java
    │   │               │   ├── BasicMonkeyServer.java
    │   │               │   ├── BasicRecorderEvent.java
    │   │               │   ├── BasicScheduler.java
    │   │               │   ├── BasicSimianArmyContext.java
    │   │               │   ├── LocalDbRecorder.java
    │   │               │   ├── calendars/
    │   │               │   │   └── BavarianCalendar.java
    │   │               │   ├── chaos/
    │   │               │   │   ├── BasicChaosEmailNotifier.java
    │   │               │   │   ├── BasicChaosInstanceSelector.java
    │   │               │   │   ├── BasicChaosMonkey.java
    │   │               │   │   ├── BasicInstanceGroup.java
    │   │               │   │   └── CloudFormationChaosMonkey.java
    │   │               │   ├── conformity/
    │   │               │   │   ├── BasicConformityEmailBuilder.java
    │   │               │   │   ├── BasicConformityMonkey.java
    │   │               │   │   └── BasicConformityMonkeyContext.java
    │   │               │   └── janitor/
    │   │               │       ├── BasicJanitorEmailBuilder.java
    │   │               │       ├── BasicJanitorMonkey.java
    │   │               │       ├── BasicJanitorMonkeyContext.java
    │   │               │       ├── BasicJanitorRuleEngine.java
    │   │               │       └── BasicVolumeTaggingMonkeyContext.java
    │   │               ├── chaos/
    │   │               │   ├── BlockAllNetworkTrafficChaosType.java
    │   │               │   ├── BurnCpuChaosType.java
    │   │               │   ├── BurnIoChaosType.java
    │   │               │   ├── ChaosCrawler.java
    │   │               │   ├── ChaosEmailNotifier.java
    │   │               │   ├── ChaosInstance.java
    │   │               │   ├── ChaosInstanceSelector.java
    │   │               │   ├── ChaosMonkey.java
    │   │               │   ├── ChaosType.java
    │   │               │   ├── DetachVolumesChaosType.java
    │   │               │   ├── FailDnsChaosType.java
    │   │               │   ├── FailDynamoDbChaosType.java
    │   │               │   ├── FailEc2ChaosType.java
    │   │               │   ├── FailS3ChaosType.java
    │   │               │   ├── FillDiskChaosType.java
    │   │               │   ├── KillProcessesChaosType.java
    │   │               │   ├── NetworkCorruptionChaosType.java
    │   │               │   ├── NetworkLatencyChaosType.java
    │   │               │   ├── NetworkLossChaosType.java
    │   │               │   ├── NullRouteChaosType.java
    │   │               │   ├── ScriptChaosType.java
    │   │               │   ├── ShutdownInstanceChaosType.java
    │   │               │   └── SshConfig.java
    │   │               ├── client/
    │   │               │   ├── MonkeyRestClient.java
    │   │               │   ├── aws/
    │   │               │   │   ├── AWSClient.java
    │   │               │   │   └── chaos/
    │   │               │   │       ├── ASGChaosCrawler.java
    │   │               │   │       ├── FilteringChaosCrawler.java
    │   │               │   │       └── TagPredicate.java
    │   │               │   ├── edda/
    │   │               │   │   └── EddaClient.java
    │   │               │   └── vsphere/
    │   │               │       ├── PropertyBasedTerminationStrategy.java
    │   │               │       ├── TerminationStrategy.java
    │   │               │       ├── VSphereClient.java
    │   │               │       ├── VSphereContext.java
    │   │               │       ├── VSphereGroups.java
    │   │               │       └── VSphereServiceConnection.java
    │   │               ├── conformity/
    │   │               │   ├── AutoScalingGroup.java
    │   │               │   ├── Cluster.java
    │   │               │   ├── ClusterCrawler.java
    │   │               │   ├── Conformity.java
    │   │               │   ├── ConformityClusterTracker.java
    │   │               │   ├── ConformityEmailBuilder.java
    │   │               │   ├── ConformityEmailNotifier.java
    │   │               │   ├── ConformityMonkey.java
    │   │               │   ├── ConformityRule.java
    │   │               │   └── ConformityRuleEngine.java
    │   │               ├── janitor/
    │   │               │   ├── AbstractJanitor.java
    │   │               │   ├── DryRunnableJanitor.java
    │   │               │   ├── DryRunnableJanitorException.java
    │   │               │   ├── Janitor.java
    │   │               │   ├── JanitorCrawler.java
    │   │               │   ├── JanitorEmailBuilder.java
    │   │               │   ├── JanitorEmailNotifier.java
    │   │               │   ├── JanitorMonkey.java
    │   │               │   ├── JanitorResourceTracker.java
    │   │               │   ├── JanitorRuleEngine.java
    │   │               │   └── Rule.java
    │   │               ├── resources/
    │   │               │   ├── chaos/
    │   │               │   │   └── ChaosMonkeyResource.java
    │   │               │   └── janitor/
    │   │               │       └── JanitorMonkeyResource.java
    │   │               └── tunable/
    │   │                   ├── TunableInstanceGroup.java
    │   │                   └── TunablyAggressiveChaosMonkey.java
    │   ├── resources/
    │   │   ├── chaos.properties
    │   │   ├── client.properties
    │   │   ├── conformity.properties
    │   │   ├── janitor.properties
    │   │   ├── log4j.properties
    │   │   ├── scripts/
    │   │   │   ├── burncpu.sh
    │   │   │   ├── burnio.sh
    │   │   │   ├── faildns.sh
    │   │   │   ├── faildynamodb.sh
    │   │   │   ├── failec2.sh
    │   │   │   ├── fails3.sh
    │   │   │   ├── filldisk.sh
    │   │   │   ├── killprocesses.sh
    │   │   │   ├── networkcorruption.sh
    │   │   │   ├── networklatency.sh
    │   │   │   ├── networkloss.sh
    │   │   │   └── nullroute.sh
    │   │   ├── simianarmy.properties
    │   │   └── volumeTagging.properties
    │   └── webapp/
    │       └── WEB-INF/
    │           └── web.xml
    └── test/
        ├── java/
        │   └── com/
        │       └── netflix/
        │           └── simianarmy/
        │               ├── TestMonkey.java
        │               ├── TestMonkeyContext.java
        │               ├── TestMonkeyRunner.java
        │               ├── TestUtils.java
        │               ├── aws/
        │               │   ├── TestAWSEmailNotifier.java
        │               │   ├── TestRDSRecorder.java
        │               │   ├── TestSimpleDBRecorder.java
        │               │   ├── conformity/
        │               │   │   ├── TestASGOwnerEmailTag.java
        │               │   │   ├── TestRDSConformityClusterTracker.java
        │               │   │   └── rule/
        │               │   │       └── TestInstanceInVPC.java
        │               │   └── janitor/
        │               │       ├── TestAWSResource.java
        │               │       ├── TestRDSJanitorResourceTracker.java
        │               │       ├── TestSimpleDBJanitorResourceTracker.java
        │               │       ├── crawler/
        │               │       │   ├── TestASGJanitorCrawler.java
        │               │       │   ├── TestEBSSnapshotJanitorCrawler.java
        │               │       │   ├── TestEBSVolumeJanitorCrawler.java
        │               │       │   ├── TestELBJanitorCrawler.java
        │               │       │   ├── TestInstanceJanitorCrawler.java
        │               │       │   └── TestLaunchConfigJanitorCrawler.java
        │               │       └── rule/
        │               │           ├── TestMonkeyCalendar.java
        │               │           ├── asg/
        │               │           │   ├── TestOldEmptyASGRule.java
        │               │           │   └── TestSuspendedASGRule.java
        │               │           ├── elb/
        │               │           │   └── TestOrphanedELBRule.java
        │               │           ├── generic/
        │               │           │   ├── TestTagValueExclusionRule.java
        │               │           │   └── TestUntaggedRule.java
        │               │           ├── instance/
        │               │           │   └── TestOrphanedInstanceRule.java
        │               │           ├── launchconfig/
        │               │           │   └── TestOldUnusedLaunchConfigRule.java
        │               │           ├── snapshot/
        │               │           │   └── TestNoGeneratedAMIRule.java
        │               │           └── volume/
        │               │               └── TestOldDetachedVolumeRule.java
        │               ├── basic/
        │               │   ├── TestBasicCalendar.java
        │               │   ├── TestBasicConfiguration.java
        │               │   ├── TestBasicContext.java
        │               │   ├── TestBasicMonkeyServer.java
        │               │   ├── TestBasicRecorderEvent.java
        │               │   ├── TestBasicScheduler.java
        │               │   ├── calendar/
        │               │   │   └── TestBavarianCalendar.java
        │               │   ├── chaos/
        │               │   │   ├── TestBasicChaosEmailNotifier.java
        │               │   │   ├── TestBasicChaosInstanceSelector.java
        │               │   │   ├── TestBasicChaosMonkey.java
        │               │   │   └── TestCloudFormationChaosMonkey.java
        │               │   └── janitor/
        │               │       └── TestBasicJanitorRuleEngine.java
        │               ├── chaos/
        │               │   ├── TestChaosMonkeyArmy.java
        │               │   └── TestChaosMonkeyContext.java
        │               ├── client/
        │               │   ├── aws/
        │               │   │   ├── TestAWSClient.java
        │               │   │   └── chaos/
        │               │   │       ├── TestASGChaosCrawler.java
        │               │   │       └── TestFilterASGChaosCrawler.java
        │               │   └── vsphere/
        │               │       ├── TestPropertyBasedTerminationStrategy.java
        │               │       ├── TestVSpehereClient.java
        │               │       ├── TestVSphereContext.java
        │               │       ├── TestVSphereGroups.java
        │               │       └── TestVSphereServiceConnection.java
        │               ├── conformity/
        │               │   ├── TestCrossZoneLoadBalancing.java
        │               │   └── TestSameZonesInElbAndAsg.java
        │               ├── janitor/
        │               │   ├── TestAbstractJanitor.java
        │               │   └── TestBasicJanitorMonkeyContext.java
        │               ├── resources/
        │               │   └── chaos/
        │               │       └── TestChaosMonkeyResource.java
        │               └── tunable/
        │                   └── TestTunablyAggressiveChaosMonkey.java
        └── resources/
            ├── chaos.properties
            ├── client.properties
            ├── com/
            │   └── netflix/
            │       └── simianarmy/
            │           ├── chaos/
            │           │   ├── all.properties
            │           │   ├── cloudformation.properties
            │           │   ├── disabled.properties
            │           │   ├── enabledA.properties
            │           │   ├── enabledAwith0.properties
            │           │   ├── enabledAwithout1.properties
            │           │   ├── enabledB.properties
            │           │   ├── fullProbability.properties
            │           │   ├── globalNotificationEnabled.properties
            │           │   ├── mandatoryTerminationDisabled.properties
            │           │   ├── mandatoryTerminationInsideWindow.properties
            │           │   ├── mandatoryTerminationNoOptInTime.properties
            │           │   ├── mandatoryTerminationNotDefined.properties
            │           │   ├── mandatoryTerminationOutsideWindow.properties
            │           │   ├── noProbability.properties
            │           │   ├── noProbabilityByName.properties
            │           │   ├── notificationEnabled.properties
            │           │   ├── ondemandTermination.properties
            │           │   ├── ondemandTerminationDisabled.properties
            │           │   ├── propertiesWithDefaults.properties
            │           │   ├── terminationPerDayAsBiggerThanOne.properties
            │           │   ├── terminationPerDayAsNegative.properties
            │           │   ├── terminationPerDayAsOne.properties
            │           │   ├── terminationPerDayAsSmallerThanOne.properties
            │           │   ├── terminationPerDayAsVerySmall.properties
            │           │   ├── terminationPerDayAsZero.properties
            │           │   ├── terminationPerDayGroupLevel.properties
            │           │   ├── unleashedEnabledA.properties
            │           │   └── unleashedEnabledB.properties
            │           └── resources/
            │               └── chaos/
            │                   └── getChaosEventsResponse.json
            ├── log4j.properties
            ├── proxy.properties
            └── simianarmy.properties
Download .txt
SYMBOL INDEX (1950 symbols across 216 files)

FILE: src/main/java/com/netflix/simianarmy/AbstractEmailBuilder.java
  class AbstractEmailBuilder (line 21) | public abstract class AbstractEmailBuilder implements EmailBuilder {
    method buildEmailBody (line 23) | @Override
    method getHeader (line 44) | protected abstract String getHeader();
    method getEntryTable (line 52) | protected abstract String getEntryTable(String emailAddress);
    method getFooter (line 57) | protected abstract String getFooter();
    method getHtmlCell (line 64) | protected String getHtmlCell(String value) {
    method getHtmlTableHeader (line 72) | protected String getHtmlTableHeader(String[] columns) {

FILE: src/main/java/com/netflix/simianarmy/CloudClient.java
  type CloudClient (line 31) | public interface CloudClient {
    method terminateInstance (line 43) | void terminateInstance(String instanceId);
    method deleteAutoScalingGroup (line 51) | void deleteAutoScalingGroup(String asgName);
    method deleteLaunchConfiguration (line 59) | void deleteLaunchConfiguration(String launchConfigName);
    method deleteVolume (line 67) | void deleteVolume(String volumeId);
    method deleteSnapshot (line 75) | void deleteSnapshot(String snapshotId);
    method deleteImage (line 82) | void deleteImage(String imageId);
    method deleteElasticLoadBalancer (line 90) | void deleteElasticLoadBalancer(String elbId);
    method deleteDNSRecord (line 102) | public void deleteDNSRecord(String dnsName, String dnsType, String hos...
    method createTagsForResources (line 113) | void createTagsForResources(Map<String, String> keyValueMap, String......
    method listAttachedVolumes (line 127) | List<String> listAttachedVolumes(String instanceId, boolean includeRoot);
    method detachVolume (line 143) | void detachVolume(String instanceId, String volumeId, boolean force);
    method getJcloudsComputeService (line 148) | ComputeService getJcloudsComputeService();
    method getJcloudsId (line 153) | String getJcloudsId(String instanceId);
    method connectSsh (line 164) | SshClient connectSsh(String instanceId, LoginCredentials credentials);
    method findSecurityGroup (line 178) | String findSecurityGroup(String instanceId, String groupName);
    method createSecurityGroup (line 192) | String createSecurityGroup(String instanceId, String groupName, String...
    method canChangeInstanceSecurityGroups (line 202) | boolean canChangeInstanceSecurityGroups(String instanceId);
    method setInstanceSecurityGroups (line 218) | void setInstanceSecurityGroups(String instanceId, List<String> groupIds);

FILE: src/main/java/com/netflix/simianarmy/EmailBuilder.java
  type EmailBuilder (line 21) | public interface EmailBuilder {
    method buildEmailBody (line 27) | String buildEmailBody(String emailAddress);

FILE: src/main/java/com/netflix/simianarmy/EventType.java
  type EventType (line 23) | public interface EventType extends NamedType {

FILE: src/main/java/com/netflix/simianarmy/FeatureNotEnabledException.java
  class FeatureNotEnabledException (line 26) | public class FeatureNotEnabledException extends Exception {
    method FeatureNotEnabledException (line 34) | public FeatureNotEnabledException(String msg) {

FILE: src/main/java/com/netflix/simianarmy/GroupType.java
  type GroupType (line 23) | public interface GroupType extends NamedType {

FILE: src/main/java/com/netflix/simianarmy/InstanceGroupNotFoundException.java
  class InstanceGroupNotFoundException (line 27) | public class InstanceGroupNotFoundException extends Exception {
    method InstanceGroupNotFoundException (line 39) | public InstanceGroupNotFoundException(String groupType, String groupNa...
    method toString (line 45) | @Override
    method errorMessage (line 50) | private static String errorMessage(String groupType, String groupName) {

FILE: src/main/java/com/netflix/simianarmy/Monkey.java
  class Monkey (line 28) | public abstract class Monkey {
    type Context (line 36) | public interface Context {
      method scheduler (line 43) | MonkeyScheduler scheduler();
      method calendar (line 50) | MonkeyCalendar calendar();
      method cloudClient (line 57) | CloudClient cloudClient();
      method recorder (line 64) | MonkeyRecorder recorder();
      method reportEvent (line 73) | void reportEvent(Event evt);
      method resetEventReport (line 78) | void resetEventReport();
      method getEventReport (line 83) | String getEventReport();
      method configuration (line 90) | MonkeyConfiguration configuration();
    method Monkey (line 102) | public Monkey(Context ctx) {
    method type (line 111) | public abstract MonkeyType type();
    method doMonkeyBusiness (line 116) | public abstract void doMonkeyBusiness();
    method context (line 123) | public Context context() {
    method run (line 130) | public void run() {
    method start (line 149) | public void start() {
    method stop (line 166) | public void stop() {

FILE: src/main/java/com/netflix/simianarmy/MonkeyCalendar.java
  type MonkeyCalendar (line 27) | public interface MonkeyCalendar {
    method isMonkeyTime (line 36) | boolean isMonkeyTime(Monkey monkey);
    method openHour (line 43) | int openHour();
    method closeHour (line 50) | int closeHour();
    method now (line 57) | Calendar now();
    method getBusinessDay (line 65) | Date getBusinessDay(Date date, int n);

FILE: src/main/java/com/netflix/simianarmy/MonkeyConfiguration.java
  type MonkeyConfiguration (line 23) | public interface MonkeyConfiguration {
    method getBool (line 32) | boolean getBool(String property);
    method getBoolOrElse (line 43) | boolean getBoolOrElse(String property, boolean dflt);
    method getNumOrElse (line 54) | double getNumOrElse(String property, double dflt);
    method getStr (line 63) | String getStr(String property);
    method getStrOrElse (line 74) | String getStrOrElse(String property, String dflt);
    method reload (line 79) | void reload();
    method reload (line 86) | void reload(String groupName);

FILE: src/main/java/com/netflix/simianarmy/MonkeyEmailNotifier.java
  type MonkeyEmailNotifier (line 22) | public interface MonkeyEmailNotifier {
    method isValidEmail (line 29) | boolean isValidEmail(String email);
    method buildEmailSubject (line 36) | String buildEmailSubject(String to);
    method getCcAddresses (line 43) | String[] getCcAddresses(String to);
    method getSourceAddress (line 50) | String getSourceAddress(String to);
    method sendEmail (line 58) | void sendEmail(String to, String subject, String body);

FILE: src/main/java/com/netflix/simianarmy/MonkeyRecorder.java
  type MonkeyRecorder (line 27) | public interface MonkeyRecorder {
    type Event (line 32) | public interface Event {
      method id (line 39) | String id();
      method eventTime (line 46) | Date eventTime();
      method monkeyType (line 53) | MonkeyType monkeyType();
      method eventType (line 60) | EventType eventType();
      method region (line 67) | String region();
      method fields (line 75) | Map<String, String> fields();
      method field (line 84) | String field(String name);
      method addField (line 95) | Event addField(String name, String value);
    method newEvent (line 111) | Event newEvent(MonkeyType monkeyType, EventType eventType, String regi...
    method newEvent (line 113) | default Event newEvent(MonkeyType monkeyType, EventType eventType, Res...
    method recordEvent (line 133) | void recordEvent(Event evt);
    method findEvents (line 144) | List<Event> findEvents(Map<String, String> query, Date after);
    method findEvents (line 157) | List<Event> findEvents(MonkeyType monkeyType, Map<String, String> quer...
    method findEvents (line 172) | List<Event> findEvents(MonkeyType monkeyType, EventType eventType, Map...

FILE: src/main/java/com/netflix/simianarmy/MonkeyRunner.java
  type MonkeyRunner (line 34) | public enum MonkeyRunner {
    method getInstance (line 47) | public static MonkeyRunner getInstance() {
    method start (line 54) | public void start() {
    method stop (line 64) | public void stop() {
    method getMonkeys (line 86) | public List<Monkey> getMonkeys() {
    method addMonkey (line 96) | public void addMonkey(Class<? extends Monkey> monkeyClass) {
    method replaceMonkey (line 106) | public void replaceMonkey(Class<? extends Monkey> monkeyClass) {
    method addMonkey (line 118) | public void addMonkey(Class<? extends Monkey> monkeyClass, Class<? ext...
    method replaceMonkey (line 135) | public void replaceMonkey(Class<? extends Monkey> monkeyClass, Class<?...
    method removeMonkey (line 155) | public void removeMonkey(Class<? extends Monkey> monkeyClass) {
    method factory (line 187) | public <T extends Monkey> T factory(Class<T> monkeyClass) {
    method factory (line 214) | public <T extends Monkey> T factory(Class<T> monkeyClass, Class<? exte...
    method getContextClass (line 248) | public Class<? extends Monkey.Context> getContextClass(Class<? extends...

FILE: src/main/java/com/netflix/simianarmy/MonkeyScheduler.java
  type MonkeyScheduler (line 25) | public interface MonkeyScheduler {
    method frequency (line 33) | int frequency();
    method frequencyUnit (line 40) | TimeUnit frequencyUnit();
    method start (line 50) | void start(Monkey monkey, Runnable run);
    method stop (line 58) | void stop(Monkey monkey);

FILE: src/main/java/com/netflix/simianarmy/MonkeyType.java
  type MonkeyType (line 23) | public interface MonkeyType extends NamedType {

FILE: src/main/java/com/netflix/simianarmy/NamedType.java
  type NamedType (line 23) | public interface NamedType {
    method name (line 28) | String name();

FILE: src/main/java/com/netflix/simianarmy/NotFoundException.java
  class NotFoundException (line 27) | @SuppressWarnings("serial")
    method NotFoundException (line 36) | public NotFoundException(String message) {
    method NotFoundException (line 48) | public NotFoundException(String message, Throwable cause) {
    method NotFoundException (line 58) | public NotFoundException(Throwable cause) {

FILE: src/main/java/com/netflix/simianarmy/Resource.java
  type Resource (line 32) | public interface Resource {
    type CleanupState (line 34) | public enum CleanupState {
    method getId (line 50) | String getId();
    method setId (line 57) | void setId(String id);
    method withId (line 65) | Resource withId(String id);
    method getResourceType (line 72) | ResourceType getResourceType();
    method setResourceType (line 79) | void setResourceType(ResourceType type);
    method withResourceType (line 87) | Resource withResourceType(ResourceType type);
    method getRegion (line 94) | String getRegion();
    method setRegion (line 101) | void setRegion(String region);
    method withRegion (line 109) | Resource withRegion(String region);
    method getOwnerEmail (line 116) | String getOwnerEmail();
    method setOwnerEmail (line 123) | void setOwnerEmail(String ownerEmail);
    method withOwnerEmail (line 131) | Resource withOwnerEmail(String ownerEmail);
    method getDescription (line 138) | String getDescription();
    method setDescription (line 145) | void setDescription(String description);
    method withDescription (line 153) | Resource withDescription(String description);
    method getLaunchTime (line 160) | Date getLaunchTime();
    method setLaunchTime (line 167) | void setLaunchTime(Date launchTime);
    method withLaunchTime (line 175) | Resource withLaunchTime(Date launchTime);
    method getMarkTime (line 182) | Date getMarkTime();
    method setMarkTime (line 189) | void setMarkTime(Date markTime);
    method withMarkTime (line 197) | Resource withMarkTime(Date markTime);
    method getExpectedTerminationTime (line 204) | Date getExpectedTerminationTime();
    method setExpectedTerminationTime (line 211) | void setExpectedTerminationTime(Date expectedTerminationTime);
    method withExpectedTerminationTime (line 219) | Resource withExpectedTerminationTime(Date expectedTerminationTime);
    method getActualTerminationTime (line 226) | Date getActualTerminationTime();
    method setActualTerminationTime (line 233) | void setActualTerminationTime(Date actualTerminationTime);
    method withActualTerminationTime (line 241) | Resource withActualTerminationTime(Date actualTerminationTime);
    method getNotificationTime (line 248) | Date getNotificationTime();
    method setNotificationTime (line 255) | void setNotificationTime(Date notificationTime);
    method withNnotificationTime (line 263) | Resource withNnotificationTime(Date notificationTime);
    method getState (line 270) | CleanupState getState();
    method setState (line 277) | void setState(CleanupState state);
    method withState (line 285) | Resource withState(CleanupState state);
    method getTerminationReason (line 292) | String getTerminationReason();
    method setTerminationReason (line 299) | void setTerminationReason(String terminationReason);
    method withTerminationReason (line 307) | Resource withTerminationReason(String terminationReason);
    method isOptOutOfJanitor (line 314) | boolean isOptOutOfJanitor();
    method setOptOutOfJanitor (line 321) | void setOptOutOfJanitor(boolean optOutOfJanitor);
    method withOptOutOfJanitor (line 329) | Resource withOptOutOfJanitor(boolean optOutOfJanitor);
    method getFieldToValueMap (line 336) | Map<String, String> getFieldToValueMap();
    method setAdditionalField (line 344) | Resource setAdditionalField(String fieldName, String fieldValue);
    method getAdditionalField (line 351) | String getAdditionalField(String fieldName);
    method getAdditionalFieldNames (line 357) | Collection<String> getAdditionalFieldNames();
    method setTag (line 364) | void setTag(String key, String value);
    method getTag (line 371) | String getTag(String key);
    method getAllTagKeys (line 377) | Collection<String> getAllTagKeys();
    method cloneResource (line 384) | Resource cloneResource();

FILE: src/main/java/com/netflix/simianarmy/ResourceType.java
  type ResourceType (line 23) | public interface ResourceType extends NamedType {

FILE: src/main/java/com/netflix/simianarmy/aws/AWSEmailNotifier.java
  class AWSEmailNotifier (line 39) | public abstract class AWSEmailNotifier implements MonkeyEmailNotifier {
    method AWSEmailNotifier (line 53) | public AWSEmailNotifier(AmazonSimpleEmailServiceClient sesClient) {
    method sendEmail (line 59) | @Override
    method isValidEmail (line 92) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/AWSResource.java
  class AWSResource (line 34) | public class AWSResource implements Resource {
    method getFieldToValueMap (line 89) | @Override
    method parseFieldtoValueMap (line 121) | public static AWSResource parseFieldtoValueMap(Map<String, String> fie...
    method getAWSResourceState (line 162) | public String getAWSResourceState() {
    method setAWSResourceState (line 166) | public void setAWSResourceState(String awsState) {
    method getId (line 171) | @Override
    method setId (line 177) | @Override
    method withId (line 183) | @Override
    method getResourceType (line 190) | @Override
    method setResourceType (line 196) | @Override
    method withResourceType (line 202) | @Override
    method getRegion (line 209) | @Override
    method setRegion (line 215) | @Override
    method withRegion (line 221) | @Override
    method getOwnerEmail (line 228) | @Override
    method setOwnerEmail (line 234) | @Override
    method withOwnerEmail (line 240) | @Override
    method getDescription (line 247) | @Override
    method setDescription (line 253) | @Override
    method withDescription (line 259) | @Override
    method getLaunchTime (line 266) | @Override
    method setLaunchTime (line 272) | @Override
    method withLaunchTime (line 278) | @Override
    method getMarkTime (line 285) | @Override
    method setMarkTime (line 291) | @Override
    method withMarkTime (line 297) | @Override
    method getExpectedTerminationTime (line 304) | @Override
    method setExpectedTerminationTime (line 310) | @Override
    method withExpectedTerminationTime (line 316) | @Override
    method getActualTerminationTime (line 323) | @Override
    method setActualTerminationTime (line 329) | @Override
    method withActualTerminationTime (line 335) | @Override
    method getNotificationTime (line 342) | @Override
    method setNotificationTime (line 348) | @Override
    method withNnotificationTime (line 354) | @Override
    method getState (line 361) | @Override
    method setState (line 367) | @Override
    method withState (line 373) | @Override
    method getTerminationReason (line 380) | @Override
    method setTerminationReason (line 386) | @Override
    method withTerminationReason (line 392) | @Override
    method isOptOutOfJanitor (line 399) | @Override
    method setOptOutOfJanitor (line 405) | @Override
    method withOptOutOfJanitor (line 411) | @Override
    method getCopyOfDate (line 417) | private static Date getCopyOfDate(Date date) {
    method putToMapIfNotNull (line 424) | private static void putToMapIfNotNull(Map<String, String> map, String ...
    method putToMapIfNotNull (line 432) | private static void putToMapIfNotNull(Map<String, String> map, String ...
    method putToMapIfNotNull (line 440) | private static void putToMapIfNotNull(Map<String, String> map, String ...
    method printDate (line 448) | private static String printDate(Date date) {
    method setAdditionalField (line 456) | @Override
    method getAdditionalField (line 464) | @Override
    method getAdditionalFieldNames (line 469) | @Override
    method cloneResource (line 474) | @Override
    method setTag (line 502) | @Override
    method getTag (line 508) | @Override
    method getAllTagKeys (line 514) | @Override
    method toString (line 519) | @Override
    method equals (line 541) | @Override
    method hashCode (line 552) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/AWSResourceType.java
  type AWSResourceType (line 26) | public enum AWSResourceType implements ResourceType {

FILE: src/main/java/com/netflix/simianarmy/aws/RDSRecorder.java
  class RDSRecorder (line 45) | @SuppressWarnings("serial")
    method RDSRecorder (line 69) | public RDSRecorder(String dbDriver, String dbUser,
    method RDSRecorder (line 87) | public RDSRecorder(JdbcTemplate jdbcTemplate, String table, String reg...
    method getJdbcTemplate (line 93) | public JdbcTemplate getJdbcTemplate() {
    method newEvent (line 98) | @Override
    method recordEvent (line 104) | @Override
    method findEvents (line 139) | @Override
    method findEvents (line 145) | @Override
    method findEvents (line 151) | @Override
    method mapEvent (line 184) | private Event mapEvent(ResultSet rs) throws SQLException {
    method init (line 212) | public void init() {

FILE: src/main/java/com/netflix/simianarmy/aws/STSAssumeRoleSessionCredentialsProvider.java
  class STSAssumeRoleSessionCredentialsProvider (line 38) | public class STSAssumeRoleSessionCredentialsProvider implements AWSCrede...
    method STSAssumeRoleSessionCredentialsProvider (line 67) | public STSAssumeRoleSessionCredentialsProvider(String roleArn) {
    method STSAssumeRoleSessionCredentialsProvider (line 83) | public STSAssumeRoleSessionCredentialsProvider(String roleArn, ClientC...
    method STSAssumeRoleSessionCredentialsProvider (line 99) | public STSAssumeRoleSessionCredentialsProvider(AWSCredentials longLive...
    method STSAssumeRoleSessionCredentialsProvider (line 116) | public STSAssumeRoleSessionCredentialsProvider(AWSCredentials longLive...
    method STSAssumeRoleSessionCredentialsProvider (line 135) | public STSAssumeRoleSessionCredentialsProvider(AWSCredentialsProvider ...
    method STSAssumeRoleSessionCredentialsProvider (line 156) | public STSAssumeRoleSessionCredentialsProvider(AWSCredentialsProvider ...
    method getCredentials (line 162) | @Override
    method refresh (line 170) | @Override
    method startSession (line 181) | private void startSession() {
    method needsNewSession (line 196) | private boolean needsNewSession() {

FILE: src/main/java/com/netflix/simianarmy/aws/SimpleDBRecorder.java
  class SimpleDBRecorder (line 54) | @SuppressWarnings("serial")
    type Keys (line 69) | private enum Keys {
    method SimpleDBRecorder (line 102) | public SimpleDBRecorder(AWSClient awsClient, String domain) {
    method sdbClient (line 115) | protected AmazonSimpleDB sdbClient() {
    method enumToValue (line 126) | public static String enumToValue(NamedType e) {
    method valueToEnum (line 137) | public static <T extends NamedType> T valueToEnum(
    method newEvent (line 166) | @Override
    method recordEvent (line 172) | @Override
    method findEvents (line 204) | protected List<Event> findEvents(Map<String, String> queryMap, long af...
    method findEvents (line 243) | @Override
    method findEvents (line 249) | @Override
    method findEvents (line 257) | @Override
    method init (line 268) | public void init() {

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/RDSConformityClusterTracker.java
  class RDSConformityClusterTracker (line 48) | public class RDSConformityClusterTracker implements ConformityClusterTra...
    method RDSConformityClusterTracker (line 63) | public RDSConformityClusterTracker(String dbDriver, String dbUser,
    method RDSConformityClusterTracker (line 80) | public RDSConformityClusterTracker(JdbcTemplate jdbcTemplate, String t...
    method getJdbcTemplate (line 85) | public JdbcTemplate getJdbcTemplate() {
    method value (line 89) | public Object value(String value) {
    method value (line 93) | public Object value(Date value) {
    method value (line 97) | public Object value(boolean value) {
    method emailValue (line 101) | public Object emailValue(String email) {
    method addOrUpdate (line 108) | @Override
    method conformitiesAsMap (line 176) | private HashMap<String,String> conformitiesAsMap(Cluster cluster) {
    method getAllClusters (line 190) | @Override
    method getNonconformingClusters (line 195) | @Override
    method getCluster (line 200) | @Override
    method mapResource (line 223) | private Cluster mapResource(ResultSet rs) throws SQLException {
    method millisToFormattedDate (line 246) | private String millisToFormattedDate(String millisStr) {
    method conformityMapFromJson (line 257) | private HashMap<String,String> conformityMapFromJson(String json) thro...
    method deleteClusters (line 275) | @Override
    method getClusters (line 287) | private List<Cluster> getClusters(Boolean conforming, String... region...
    method init (line 320) | public void init() {

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/SimpleDBConformityClusterTracker.java
  class SimpleDBConformityClusterTracker (line 45) | public class SimpleDBConformityClusterTracker implements ConformityClust...
    method SimpleDBConformityClusterTracker (line 66) | public SimpleDBConformityClusterTracker(AWSClient awsClient, String do...
    method getSimpleDBClient (line 77) | protected AmazonSimpleDB getSimpleDBClient() {
    method addOrUpdate (line 82) | @Override
    method getAllClusters (line 103) | @Override
    method getNonconformingClusters (line 108) | @Override
    method getCluster (line 113) | @Override
    method deleteClusters (line 140) | @Override
    method getClusters (line 151) | private List<Cluster> getClusters(Boolean conforming, String... region...
    method parseCluster (line 190) | protected Cluster parseCluster(Item item) {
    method getSimpleDBItemName (line 208) | protected String getSimpleDBItemName(Cluster cluster) {
    method querySimpleDBItems (line 212) | private List<Item> querySimpleDBItems(String query) {

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/crawler/AWSClusterCrawler.java
  class AWSClusterCrawler (line 44) | public class AWSClusterCrawler implements ClusterCrawler {
    method AWSClusterCrawler (line 61) | public AWSClusterCrawler(Map<String, AWSClient> regionToAwsClient, Mon...
    method clusters (line 76) | @Override
    method updateCluster (line 137) | private void updateCluster(Cluster cluster) {
    method getOwnerEmailForCluster (line 155) | @Override
    method updateExcludedConformityRules (line 176) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/BasicConformityEurekaClient.java
  class BasicConformityEurekaClient (line 33) | public class BasicConformityEurekaClient implements ConformityEurekaClie...
    method BasicConformityEurekaClient (line 42) | public BasicConformityEurekaClient(DiscoveryClient discoveryClient) {
    method hasHealthCheckUrl (line 46) | @Override
    method hasStatusUrl (line 58) | @Override
    method isHealthy (line 70) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/ConformityEurekaClient.java
  type ConformityEurekaClient (line 23) | public interface ConformityEurekaClient {
    method hasHealthCheckUrl (line 30) | boolean hasHealthCheckUrl(String region, String instanceId);
    method hasStatusUrl (line 38) | boolean hasStatusUrl(String region, String instanceId);
    method isHealthy (line 46) | boolean isHealthy(String region, String instanceId);

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/CrossZoneLoadBalancing.java
  class CrossZoneLoadBalancing (line 44) | public class CrossZoneLoadBalancing implements ConformityRule {
    method CrossZoneLoadBalancing (line 58) | public CrossZoneLoadBalancing() {
    method CrossZoneLoadBalancing (line 66) | public CrossZoneLoadBalancing(AWSCredentialsProvider awsCredentialsPro...
    method check (line 70) | @Override
    method isCrossZoneLoadBalancingEnabled (line 96) | protected boolean isCrossZoneLoadBalancingEnabled(String region, Strin...
    method getName (line 101) | @Override
    method getNonconformingReason (line 106) | @Override
    method getLoadBalancerNamesForAsg (line 117) | protected List<String> getLoadBalancerNamesForAsg(String region, Strin...
    method getAwsClient (line 128) | private AWSClient getAwsClient(String region) {

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceHasHealthCheckUrl.java
  class InstanceHasHealthCheckUrl (line 35) | public class InstanceHasHealthCheckUrl implements ConformityRule {
    method InstanceHasHealthCheckUrl (line 48) | public InstanceHasHealthCheckUrl(ConformityEurekaClient conformityEure...
    method check (line 53) | @Override
    method getName (line 71) | @Override
    method getNonconformingReason (line 76) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceHasStatusUrl.java
  class InstanceHasStatusUrl (line 34) | public class InstanceHasStatusUrl implements ConformityRule {
    method InstanceHasStatusUrl (line 47) | public InstanceHasStatusUrl(ConformityEurekaClient conformityEurekaCli...
    method check (line 52) | @Override
    method getName (line 70) | @Override
    method getNonconformingReason (line 75) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceInSecurityGroup.java
  class InstanceInSecurityGroup (line 45) | public class InstanceInSecurityGroup implements ConformityRule {
    method InstanceInSecurityGroup (line 60) | public InstanceInSecurityGroup(String... requiredSecurityGroupNames) {
    method InstanceInSecurityGroup (line 71) | public InstanceInSecurityGroup(AWSCredentialsProvider awsCredentialsPr...
    method check (line 83) | @Override
    method getName (line 105) | @Override
    method getNonconformingReason (line 110) | @Override
    method checkSecurityGroups (line 124) | protected boolean checkSecurityGroups(Collection<String> sgNames) {
    method getInstanceSecurityGroups (line 144) | protected Map<String, List<String>> getInstanceSecurityGroups(String r...

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceInVPC.java
  class InstanceInVPC (line 43) | public class InstanceInVPC implements ConformityRule {
    method InstanceInVPC (line 58) | public InstanceInVPC() {
    method InstanceInVPC (line 67) | public InstanceInVPC(AWSCredentialsProvider awsCredentialsProvider) {
    method check (line 71) | @Override
    method getName (line 88) | @Override
    method getNonconformingReason (line 93) | @Override
    method getAwsClient (line 98) | private AWSClient getAwsClient(String region) {
    method checkInstancesInVPC (line 107) | private Set<String> checkInstancesInVPC(String region, Collection<Stri...
    method getAWSInstances (line 126) | protected List<Instance> getAWSInstances(String region, String instanc...

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceIsHealthyInEureka.java
  class InstanceIsHealthyInEureka (line 34) | public class InstanceIsHealthyInEureka implements ConformityRule {
    method InstanceIsHealthyInEureka (line 47) | public InstanceIsHealthyInEureka(ConformityEurekaClient conformityEure...
    method check (line 52) | @Override
    method getName (line 71) | @Override
    method getNonconformingReason (line 76) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceTooOld.java
  class InstanceTooOld (line 44) | public class InstanceTooOld implements ConformityRule {
    method InstanceTooOld (line 58) | public InstanceTooOld(int instanceAgeThreshold) {
    method InstanceTooOld (line 69) | public InstanceTooOld(AWSCredentialsProvider awsCredentialsProvider, i...
    method check (line 76) | @Override
    method getName (line 98) | @Override
    method getNonconformingReason (line 103) | @Override
    method getInstanceLaunchTimes (line 119) | protected Map<String, Long> getInstanceLaunchTimes(String region, Stri...

FILE: src/main/java/com/netflix/simianarmy/aws/conformity/rule/SameZonesInElbAndAsg.java
  class SameZonesInElbAndAsg (line 41) | public class SameZonesInElbAndAsg implements ConformityRule {
    method SameZonesInElbAndAsg (line 55) | public SameZonesInElbAndAsg() {
    method SameZonesInElbAndAsg (line 63) | public SameZonesInElbAndAsg(AWSCredentialsProvider awsCredentialsProvi...
    method check (line 67) | @Override
    method getName (line 88) | @Override
    method getNonconformingReason (line 93) | @Override
    method getLoadBalancerNamesForAsg (line 104) | protected List<String> getLoadBalancerNamesForAsg(String region, Strin...
    method getAvailabilityZonesForAsg (line 121) | protected List<String> getAvailabilityZonesForAsg(String region, Strin...
    method getAvailabilityZonesForLoadBalancer (line 138) | protected List<String> getAvailabilityZonesForLoadBalancer(String regi...
    method getAwsClient (line 149) | private AWSClient getAwsClient(String region) {
    method haveSameZones (line 159) | private boolean haveSameZones(List<String> zones1, List<String> zones2) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/ASGJanitor.java
  class ASGJanitor (line 32) | public class ASGJanitor extends AbstractJanitor {
    method ASGJanitor (line 44) | public ASGJanitor(AWSClient awsClient, AbstractJanitor.Context ctx) {
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/EBSSnapshotJanitor.java
  class EBSSnapshotJanitor (line 32) | public class EBSSnapshotJanitor extends AbstractJanitor {
    method EBSSnapshotJanitor (line 44) | public EBSSnapshotJanitor(AWSClient awsClient, AbstractJanitor.Context...
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/EBSVolumeJanitor.java
  class EBSVolumeJanitor (line 32) | public class EBSVolumeJanitor extends AbstractJanitor {
    method EBSVolumeJanitor (line 44) | public EBSVolumeJanitor(AWSClient awsClient, AbstractJanitor.Context c...
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/ELBJanitor.java
  class ELBJanitor (line 33) | public class ELBJanitor extends AbstractJanitor {
    method ELBJanitor (line 45) | public ELBJanitor(AWSClient awsClient, Context ctx) {
    method postMark (line 51) | @Override
    method cleanup (line 55) | @Override
    method postCleanup (line 88) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/ImageJanitor.java
  class ImageJanitor (line 32) | public class ImageJanitor extends AbstractJanitor {
    method ImageJanitor (line 44) | public ImageJanitor(AWSClient awsClient, AbstractJanitor.Context ctx) {
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/InstanceJanitor.java
  class InstanceJanitor (line 32) | public class InstanceJanitor extends AbstractJanitor {
    method InstanceJanitor (line 44) | public InstanceJanitor(AWSClient awsClient, AbstractJanitor.Context ct...
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/LaunchConfigJanitor.java
  class LaunchConfigJanitor (line 32) | public class LaunchConfigJanitor extends AbstractJanitor {
    method LaunchConfigJanitor (line 44) | public LaunchConfigJanitor(AWSClient awsClient, AbstractJanitor.Contex...
    method postMark (line 50) | @Override
    method cleanup (line 54) | @Override
    method postCleanup (line 60) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/RDSJanitorResourceTracker.java
  class RDSJanitorResourceTracker (line 46) | public class RDSJanitorResourceTracker implements JanitorResourceTracker {
    method RDSJanitorResourceTracker (line 61) | public RDSJanitorResourceTracker(String dbDriver, String dbUser,
    method RDSJanitorResourceTracker (line 78) | public RDSJanitorResourceTracker(JdbcTemplate jdbcTemplate, String tab...
    method getJdbcTemplate (line 83) | public JdbcTemplate getJdbcTemplate() {
    method value (line 87) | public Object value(String value) {
    method value (line 91) | public Object value(Date value) {
    method value (line 95) | public Object value(boolean value) {
    method emailValue (line 99) | public Object emailValue(String email) {
    method addOrUpdate (line 106) | @Override
    method getResources (line 200) | @Override
    method mapResource (line 226) | private Resource mapResource(ResultSet rs) throws SQLException {
    method millisToFormattedDate (line 283) | private String millisToFormattedDate(String millisStr) {
    method getResource (line 294) | @Override
    method getResource (line 317) | @Override
    method init (line 344) | public void init() {
    method additionalFieldsAsMap (line 385) | private HashMap<String, String> additionalFieldsAsMap(Resource resourc...

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/SimpleDBJanitorResourceTracker.java
  class SimpleDBJanitorResourceTracker (line 40) | public class SimpleDBJanitorResourceTracker implements JanitorResourceTr...
    method SimpleDBJanitorResourceTracker (line 59) | public SimpleDBJanitorResourceTracker(AWSClient awsClient, String doma...
    method getSimpleDBClient (line 68) | protected AmazonSimpleDB getSimpleDBClient() {
    method addOrUpdate (line 73) | @Override
    method getResources (line 92) | @Override
    method getResource (line 123) | @Override
    method getResource (line 148) | @Override
    method parseResource (line 179) | protected Resource parseResource(Item item) {
    method getSimpleDBItemName (line 197) | protected String getSimpleDBItemName(Resource resource) {
    method querySimpleDBItems (line 201) | private List<Item> querySimpleDBItems(String query) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/VolumeTaggingMonkey.java
  class VolumeTaggingMonkey (line 55) | public class VolumeTaggingMonkey extends Monkey {
    type Context (line 63) | public interface Context extends Monkey.Context {
      method configuration (line 69) | @Override
      method awsClients (line 77) | Collection<AWSClient> awsClients();
    method VolumeTaggingMonkey (line 91) | public VolumeTaggingMonkey(Context ctx) {
    type Type (line 113) | public enum Type implements MonkeyType {
    type EventTypes (line 121) | public enum EventTypes implements EventType {
    method type (line 126) | @Override
    method doMonkeyBusiness (line 131) | @Override
    method tagVolumesWithLatestAttachment (line 144) | private void tagVolumesWithLatestAttachment(AWSClient awsClient) {
    method getOwnerEmail (line 205) | private String getOwnerEmail(String instanceId, Map<String, String> ja...
    method parseJanitorTag (line 229) | private static Map<String, String> parseJanitorTag(List<Tag> tags) {
    method parseJanitorMetaTag (line 239) | public static Map<String, String> parseJanitorMetaTag(String janitorMe...
    method getOwnerEmailDomain (line 256) | protected String getOwnerEmailDomain() {
    method updateJanitorMetaTag (line 260) | private Event updateJanitorMetaTag(Volume volume, String instance, Str...
    method makeMetaTag (line 292) | public static String makeMetaTag(String instance, String owner, Date l...
    method getTagValue (line 302) | private static String getTagValue(String key, List<Tag> tags) {
    method needsUpdate (line 315) | private static boolean needsUpdate(Map<String, String> metadata,

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/ASGJanitorCrawler.java
  class ASGJanitorCrawler (line 51) | public class ASGJanitorCrawler extends AbstractAWSJanitorCrawler {
    method ASGJanitorCrawler (line 91) | public ASGJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 95) | @Override
    method resources (line 100) | @Override
    method resources (line 108) | @Override
    method getASGResources (line 113) | private List<Resource> getASGResources(String... asgNames) {
    method getSuspensionTimeString (line 172) | private String getSuspensionTimeString(String suspensionReason) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/AbstractAWSJanitorCrawler.java
  class AbstractAWSJanitorCrawler (line 30) | public abstract class AbstractAWSJanitorCrawler implements JanitorCrawler {
    method AbstractAWSJanitorCrawler (line 38) | public AbstractAWSJanitorCrawler(AWSClient awsClient) {
    method getOwnerEmailForResource (line 48) | @Override
    method getAWSClient (line 58) | protected AWSClient getAWSClient() {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/EBSSnapshotJanitorCrawler.java
  class EBSSnapshotJanitorCrawler (line 49) | public class EBSSnapshotJanitorCrawler extends AbstractAWSJanitorCrawler {
    method EBSSnapshotJanitorCrawler (line 66) | public EBSSnapshotJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 70) | @Override
    method resources (line 75) | @Override
    method resources (line 83) | @Override
    method getSnapshotResources (line 88) | private List<Resource> getSnapshotResources(String... snapshotIds) {
    method getOwnerEmailForResource (line 114) | @Override
    method getAMIsForSnapshot (line 128) | protected Collection<String> getAMIsForSnapshot(String snapshotId) {
    method refreshSnapshotToAMIs (line 137) | private void refreshSnapshotToAMIs() {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/EBSVolumeJanitorCrawler.java
  class EBSVolumeJanitorCrawler (line 43) | public class EBSVolumeJanitorCrawler extends AbstractAWSJanitorCrawler {
    method EBSVolumeJanitorCrawler (line 52) | public EBSVolumeJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 56) | @Override
    method resources (line 61) | @Override
    method resources (line 69) | @Override
    method getVolumeResources (line 74) | private List<Resource> getVolumeResources(String... volumeIds) {
    method getVolumeDescription (line 96) | private String getVolumeDescription(Volume volume) {
    method getOwnerEmailForResource (line 106) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/ELBJanitorCrawler.java
  class ELBJanitorCrawler (line 40) | public class ELBJanitorCrawler extends AbstractAWSJanitorCrawler {
    method ELBJanitorCrawler (line 50) | public ELBJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 54) | @Override
    method resources (line 59) | @Override
    method resources (line 67) | @Override
    method getELBResources (line 72) | private List<Resource> getELBResources(String... elbNames) {
    method buildELBtoASGMap (line 127) | private Map<String, List<String>> buildELBtoASGMap() {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/InstanceJanitorCrawler.java
  class InstanceJanitorCrawler (line 43) | public class InstanceJanitorCrawler extends AbstractAWSJanitorCrawler {
    method InstanceJanitorCrawler (line 59) | public InstanceJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 63) | @Override
    method resources (line 68) | @Override
    method resources (line 76) | @Override
    method getInstanceResources (line 81) | private List<Resource> getInstanceResources(String... instanceIds) {
    method getAsgName (line 120) | private String getAsgName(Resource instanceResource, Map<String, AutoS...
    method getOpsWorksStackName (line 134) | private String getOpsWorksStackName(Resource instanceResource) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/LaunchConfigJanitorCrawler.java
  class LaunchConfigJanitorCrawler (line 42) | public class LaunchConfigJanitorCrawler extends AbstractAWSJanitorCrawler {
    method LaunchConfigJanitorCrawler (line 56) | public LaunchConfigJanitorCrawler(AWSClient awsClient) {
    method resourceTypes (line 60) | @Override
    method resources (line 65) | @Override
    method resources (line 73) | @Override
    method getLaunchConfigResources (line 78) | private List<Resource> getLaunchConfigResources(String... launchConfig...

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaASGJanitorCrawler.java
  class EddaASGJanitorCrawler (line 50) | public class EddaASGJanitorCrawler implements JanitorCrawler {
    method EddaASGJanitorCrawler (line 93) | public EddaASGJanitorCrawler(EddaClient eddaClient, String... regions) {
    method resourceTypes (line 102) | @Override
    method resources (line 107) | @Override
    method resources (line 115) | @Override
    method getOwnerEmailForResource (line 120) | @Override
    method getASGResources (line 126) | private List<Resource> getASGResources(String... asgNames) {
    method getASGResourcesInRegion (line 135) | private List<Resource> getASGResourcesInRegion(String region, String.....
    method parseJsonElementToresource (line 166) | private Resource parseJsonElementToresource(String region, JsonNode js...
    method getLaunchConfigCreationTimes (line 245) | private Map<String, Long> getLaunchConfigCreationTimes(String region) {
    method getSuspensionTimeString (line 271) | private String getSuspensionTimeString(String suspensionReason) {
    method refreshAsgLastChangeTime (line 282) | private void refreshAsgLastChangeTime() {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaEBSSnapshotJanitorCrawler.java
  class EddaEBSSnapshotJanitorCrawler (line 47) | public class EddaEBSSnapshotJanitorCrawler implements JanitorCrawler {
    method EddaEBSSnapshotJanitorCrawler (line 73) | public EddaEBSSnapshotJanitorCrawler(String defaultOwnerId, EddaClient...
    method resourceTypes (line 83) | @Override
    method resources (line 88) | @Override
    method resources (line 96) | @Override
    method getSnapshotResources (line 101) | private List<Resource> getSnapshotResources(String... snapshotIds) {
    method getSnapshotResourcesInRegion (line 109) | private List<Resource> getSnapshotResourcesInRegion(String region, Str...
    method parseJsonElementToSnapshotResource (line 148) | private Resource parseJsonElementToSnapshotResource(String region, Jso...
    method getOwnerEmailForResource (line 181) | @Override
    method getAMIsForSnapshot (line 191) | protected Collection<String> getAMIsForSnapshot(String snapshotId) {
    method refreshSnapshotToAMIs (line 200) | private void refreshSnapshotToAMIs(String region) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaEBSVolumeJanitorCrawler.java
  class EddaEBSVolumeJanitorCrawler (line 46) | public class EddaEBSVolumeJanitorCrawler implements JanitorCrawler {
    method EddaEBSVolumeJanitorCrawler (line 84) | public EddaEBSVolumeJanitorCrawler(EddaClient eddaClient, String... re...
    method updateInstanceToOwner (line 95) | private void updateInstanceToOwner(String region) {
    method resourceTypes (line 132) | @Override
    method resources (line 137) | @Override
    method resources (line 145) | @Override
    method getOwnerEmailForResource (line 150) | @Override
    method getVolumeResources (line 156) | private List<Resource> getVolumeResources(String... volumeIds) {
    method getUnattachedVolumeResourcesInRegion (line 171) | private List<Resource> getUnattachedVolumeResourcesInRegion(String reg...
    method parseJsonElementToVolumeResource (line 200) | private Resource parseJsonElementToVolumeResource(String region, JsonN...
    method addLastAttachmentInfo (line 239) | private void addLastAttachmentInfo(List<Resource> resources) {
    method setAttachmentInfo (line 308) | private void setAttachmentInfo(String volumeId, JsonNode attachment, D...
    method makeMetaTag (line 334) | private String makeMetaTag(String instance, String owner, DateTime las...
    method getBatchUrl (line 345) | private String getBatchUrl(String region, List<Resource> batch) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaELBJanitorCrawler.java
  class EddaELBJanitorCrawler (line 42) | public class EddaELBJanitorCrawler implements JanitorCrawler {
    class DNSEntry (line 44) | class DNSEntry {
    method EddaELBJanitorCrawler (line 69) | public EddaELBJanitorCrawler(EddaClient eddaClient, String fallbackOwn...
    method resourceTypes (line 80) | @Override
    method resources (line 85) | @Override
    method resources (line 93) | @Override
    method getOwnerEmailForResource (line 98) | @Override
    method getELBResources (line 120) | private List<Resource> getELBResources(String... instanceIds) {
    method getELBResourcesInRegion (line 132) | private List<Resource> getELBResourcesInRegion(String region, String.....
    method buildELBtoASGMap (line 205) | private Map<String, List<String>> buildELBtoASGMap(String region) {
    method parseJsonElementToELBResource (line 246) | private Resource parseJsonElementToELBResource(String region, JsonNode...
    method buildELBtoDNSMap (line 299) | private Map<String, List<DNSEntry>> buildELBtoDNSMap(String region) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaImageJanitorCrawler.java
  class EddaImageJanitorCrawler (line 49) | public class EddaImageJanitorCrawler implements JanitorCrawler {
    method EddaImageJanitorCrawler (line 91) | public EddaImageJanitorCrawler(EddaClient eddaClient, String ownerId, ...
    method resourceTypes (line 103) | @Override
    method resources (line 108) | @Override
    method resources (line 116) | @Override
    method getOwnerEmailForResource (line 121) | @Override
    method getAMIResources (line 127) | private List<Resource> getAMIResources(String... imageIds) {
    method getExcludedImageIds (line 156) | protected Collection<String> getExcludedImageIds() {
    method getImagesInJson (line 160) | private JsonNode getImagesInJson(String region, String... imageIds) {
    method refreshIdToNameMap (line 190) | private void refreshIdToNameMap() {
    method refreshIdToCreationTime (line 208) | private void refreshIdToCreationTime() {
    method getAMIResourcesInRegion (line 246) | private List<Resource> getAMIResourcesInRegion(String region,
    method parseJsonElementToresource (line 287) | private Resource parseJsonElementToresource(String region, JsonNode js...
    method refreshAMIsUsedByInstance (line 331) | private void refreshAMIsUsedByInstance() {
    method refreshAMIsUsedByLC (line 360) | private void refreshAMIsUsedByLC() {
    method addLastReferenceInfo (line 389) | private void addLastReferenceInfo(List<Resource> resources, long since) {
    method updateReferenceTimeByInstance (line 414) | private void updateReferenceTimeByInstance(String region, List<Resourc...
    method updateReferenceTimeByLaunchConfig (line 451) | private void updateReferenceTimeByLaunchConfig(String region, List<Res...
    method getInstanceBatchUrl (line 489) | private String getInstanceBatchUrl(String region, List<Resource> batch...
    method getLaunchConfigBatchUrl (line 498) | private String getLaunchConfigBatchUrl(String region, List<Resource> b...
    method getImageIdsString (line 507) | private String getImageIdsString(List<Resource> resources) {
    method getBaseAmiIdFromDescription (line 521) | private static String getBaseAmiIdFromDescription(String imageDescript...

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaInstanceJanitorCrawler.java
  class EddaInstanceJanitorCrawler (line 53) | public class EddaInstanceJanitorCrawler implements JanitorCrawler {
    method EddaInstanceJanitorCrawler (line 74) | public EddaInstanceJanitorCrawler(EddaClient eddaClient, String... reg...
    method resourceTypes (line 83) | @Override
    method resources (line 88) | @Override
    method resources (line 96) | @Override
    method getOwnerEmailForResource (line 101) | @Override
    method getInstanceResources (line 107) | private List<Resource> getInstanceResources(String... instanceIds) {
    method getInstanceResourcesInRegion (line 115) | private List<Resource> getInstanceResourcesInRegion(String region, Str...
    method parseJsonElementToInstanceResource (line 148) | private Resource parseJsonElementToInstanceResource(String region, Jso...
    method refreshAsgInstances (line 201) | private void refreshAsgInstances() {
    method refreshOwnerByImage (line 237) | private void refreshOwnerByImage(String region, List<Resource> resourc...

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaLaunchConfigJanitorCrawler.java
  class EddaLaunchConfigJanitorCrawler (line 46) | public class EddaLaunchConfigJanitorCrawler implements JanitorCrawler {
    method EddaLaunchConfigJanitorCrawler (line 66) | public EddaLaunchConfigJanitorCrawler(EddaClient eddaClient, String......
    method resourceTypes (line 75) | @Override
    method resources (line 80) | @Override
    method resources (line 88) | @Override
    method getLaunchConfigResources (line 93) | private List<Resource> getLaunchConfigResources(String... launchConfig...
    method getOwnerEmailForResource (line 101) | @Override
    method getLaunchConfigResourcesInRegion (line 107) | private List<Resource> getLaunchConfigResourcesInRegion(String region,...
    method getLaunchConfigsInUse (line 153) | private Set<String> getLaunchConfigsInUse(String region) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaUtils.java
  class EddaUtils (line 35) | public class EddaUtils {
    method getAllApplicationOwnerEmails (line 39) | public static Map<String, String> getAllApplicationOwnerEmails(EddaCli...

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/ami/UnusedImageRule.java
  class UnusedImageRule (line 36) | public class UnusedImageRule  implements Rule {
    method UnusedImageRule (line 55) | public UnusedImageRule(MonkeyCalendar calendar, int retentionDays, int...
    method isValid (line 64) | @Override
    method getRefTimeInMilis (line 106) | private long getRefTimeInMilis(Resource resource, String field) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/ASGInstanceValidator.java
  type ASGInstanceValidator (line 26) | public interface ASGInstanceValidator {
    method hasActiveInstance (line 32) | boolean hasActiveInstance(Resource resource);

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/DiscoveryASGInstanceValidator.java
  class DiscoveryASGInstanceValidator (line 38) | public class DiscoveryASGInstanceValidator implements ASGInstanceValidat...
    method DiscoveryASGInstanceValidator (line 48) | public DiscoveryASGInstanceValidator(DiscoveryClient discoveryClient) {
    method hasActiveInstance (line 54) | @Override
    method isActiveInstance (line 88) | private boolean isActiveInstance(String instanceId) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/DummyASGInstanceValidator.java
  class DummyASGInstanceValidator (line 29) | public class DummyASGInstanceValidator implements ASGInstanceValidator {
    method hasActiveInstance (line 34) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/OldEmptyASGRule.java
  class OldEmptyASGRule (line 39) | public class OldEmptyASGRule implements Rule {
    method OldEmptyASGRule (line 63) | public OldEmptyASGRule(MonkeyCalendar calendar, int launchConfigAgeThr...
    method OldEmptyASGRule (line 84) | public OldEmptyASGRule(MonkeyCalendar calendar, int launchConfigAgeThr...
    method isValid (line 99) | @Override
    method markResource (line 155) | private void markResource(Resource resource, DateTime now) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/SuspendedASGRule.java
  class SuspendedASGRule (line 38) | public class SuspendedASGRule implements Rule {
    method SuspendedASGRule (line 62) | public SuspendedASGRule(MonkeyCalendar calendar, int suspensionAgeThre...
    method isValid (line 75) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/elb/OrphanedELBRule.java
  class OrphanedELBRule (line 36) | public class OrphanedELBRule implements Rule {
    method OrphanedELBRule (line 53) | public OrphanedELBRule(MonkeyCalendar calendar, int retentionDays) {
    method isValid (line 60) | @Override
    method markResource (line 90) | private void markResource(Resource resource) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/generic/TagValueExclusionRule.java
  class TagValueExclusionRule (line 37) | public class TagValueExclusionRule implements Rule {
    method TagValueExclusionRule (line 49) | public TagValueExclusionRule(Map<String, String> tags) {
    method TagValueExclusionRule (line 64) | public TagValueExclusionRule(String[] names, String[] values) {
    method isValid (line 73) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/generic/UntaggedRule.java
  class UntaggedRule (line 39) | public class UntaggedRule implements Rule {
    method UntaggedRule (line 63) | public UntaggedRule(MonkeyCalendar calendar, Set<String> tagNames, int...
    method isValid (line 72) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/instance/OrphanedInstanceRule.java
  class OrphanedInstanceRule (line 39) | public class OrphanedInstanceRule implements Rule {
    method OrphanedInstanceRule (line 73) | public OrphanedInstanceRule(MonkeyCalendar calendar,
    method OrphanedInstanceRule (line 86) | public OrphanedInstanceRule(MonkeyCalendar calendar,
    method isValid (line 91) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/launchconfig/OldUnusedLaunchConfigRule.java
  class OldUnusedLaunchConfigRule (line 39) | public class OldUnusedLaunchConfigRule implements Rule {
    method OldUnusedLaunchConfigRule (line 62) | public OldUnusedLaunchConfigRule(MonkeyCalendar calendar, int ageThres...
    method isValid (line 71) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/snapshot/NoGeneratedAMIRule.java
  class NoGeneratedAMIRule (line 42) | public class NoGeneratedAMIRule implements Rule {
    method NoGeneratedAMIRule (line 71) | public NoGeneratedAMIRule(MonkeyCalendar calendar, int ageThreshold, i...
    method NoGeneratedAMIRule (line 89) | public NoGeneratedAMIRule(MonkeyCalendar calendar, int ageThreshold, i...
    method isValid (line 99) | @Override
    method hasGeneratedImage (line 165) | protected boolean hasGeneratedImage(Resource resource) {

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/volume/DeleteOnTerminationRule.java
  class DeleteOnTerminationRule (line 42) | public class DeleteOnTerminationRule implements Rule {
    method DeleteOnTerminationRule (line 68) | public DeleteOnTerminationRule(MonkeyCalendar calendar, int retentionD...
    method isValid (line 75) | @Override

FILE: src/main/java/com/netflix/simianarmy/aws/janitor/rule/volume/OldDetachedVolumeRule.java
  class OldDetachedVolumeRule (line 42) | public class OldDetachedVolumeRule implements Rule {
    method OldDetachedVolumeRule (line 68) | public OldDetachedVolumeRule(MonkeyCalendar calendar, int detachDaysTh...
    method isValid (line 77) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/BasicCalendar.java
  class BasicCalendar (line 38) | public class BasicCalendar implements MonkeyCalendar {
    method BasicCalendar (line 64) | public BasicCalendar(MonkeyConfiguration cfg) {
    method BasicCalendar (line 81) | public BasicCalendar(int open, int close, TimeZone timezone) {
    method BasicCalendar (line 97) | public BasicCalendar(MonkeyConfiguration cfg, int open, int close, Tim...
    method openHour (line 105) | @Override
    method closeHour (line 111) | @Override
    method now (line 117) | @Override
    method isMonkeyTime (line 123) | @Override
    method isHoliday (line 164) | protected boolean isHoliday(Calendar now) {
    method loadHolidays (line 177) | protected void loadHolidays(int year) {
    method dayOfYear (line 238) | protected int dayOfYear(int year, int month, int day) {
    method dayOfYear (line 259) | protected int dayOfYear(int year, int month, int dayOfWeek, int weekIn...
    method workDayInYear (line 279) | protected int workDayInYear(int year, int month, int day) {
    method getBusinessDay (line 298) | @Override
    method isWeekend (line 309) | private boolean isWeekend(Calendar calendar) {

FILE: src/main/java/com/netflix/simianarmy/basic/BasicChaosMonkeyContext.java
  class BasicChaosMonkeyContext (line 39) | public class BasicChaosMonkeyContext extends BasicSimianArmyContext impl...
    method BasicChaosMonkeyContext (line 53) | public BasicChaosMonkeyContext() {
    method chaosCrawler (line 70) | @Override
    method setChaosCrawler (line 81) | protected void setChaosCrawler(ChaosCrawler chaosCrawler) {
    method chaosInstanceSelector (line 86) | @Override
    method setChaosInstanceSelector (line 97) | protected void setChaosInstanceSelector(ChaosInstanceSelector chaosIns...
    method chaosEmailNotifier (line 101) | @Override
    method setChaosEmailNotifier (line 112) | protected void setChaosEmailNotifier(ChaosEmailNotifier notifier) {

FILE: src/main/java/com/netflix/simianarmy/basic/BasicConfiguration.java
  class BasicConfiguration (line 28) | public class BasicConfiguration implements MonkeyConfiguration {
    method BasicConfiguration (line 41) | public BasicConfiguration(Properties props) {
    method getBool (line 46) | @Override
    method getBoolOrElse (line 52) | @Override
    method getNumOrElse (line 63) | @Override
    method getStr (line 78) | @Override
    method getStrOrElse (line 84) | @Override
    method reload (line 91) | @Override
    method reload (line 96) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/BasicMonkeyServer.java
  class BasicMonkeyServer (line 41) | @SuppressWarnings("serial")
    method addMonkeysToRun (line 50) | @SuppressWarnings("unchecked")
    method init (line 74) | @Override
    method configureClient (line 87) | @SuppressWarnings("rawtypes")
    method loadClientClass (line 98) | @SuppressWarnings("rawtypes")
    method loadClientConfigProperties (line 122) | private Properties loadClientConfigProperties() throws ServletException {
    method destroy (line 144) | @SuppressWarnings("unchecked")

FILE: src/main/java/com/netflix/simianarmy/basic/BasicRecorderEvent.java
  class BasicRecorderEvent (line 32) | public class BasicRecorderEvent implements MonkeyRecorder.Event {
    method BasicRecorderEvent (line 64) | public BasicRecorderEvent(MonkeyType monkeyType, EventType eventType, ...
    method BasicRecorderEvent (line 86) | public BasicRecorderEvent(MonkeyType monkeyType, EventType eventType, ...
    method id (line 95) | public String id() {
    method region (line 100) | public String region() {
    method eventTime (line 105) | public Date eventTime() {
    method monkeyType (line 110) | public MonkeyType monkeyType() {
    method eventType (line 115) | public EventType eventType() {
    method fields (line 120) | public Map<String, String> fields() {
    method field (line 125) | public String field(String name) {
    method addFields (line 136) | public MonkeyRecorder.Event addFields(Map<String, String> toAdd) {
    method addField (line 142) | public MonkeyRecorder.Event addField(String name, String value) {

FILE: src/main/java/com/netflix/simianarmy/basic/BasicScheduler.java
  class BasicScheduler (line 40) | public class BasicScheduler implements MonkeyScheduler {
    method BasicScheduler (line 60) | public BasicScheduler() {
    method BasicScheduler (line 74) | public BasicScheduler(int freq, TimeUnit freqUnit, int concurrent) {
    method frequency (line 81) | @Override
    method frequencyUnit (line 87) | @Override
    method start (line 93) | @Override
    method stop (line 121) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/BasicSimianArmyContext.java
  class BasicSimianArmyContext (line 50) | public class BasicSimianArmyContext implements Monkey.Context {
    method BasicSimianArmyContext (line 108) | protected BasicSimianArmyContext(String... configFiles) {
    method isSafeToLog (line 181) | protected boolean isSafeToLog(Object propertyKey) {
    method loadConfigurationFileIntoProperties (line 188) | protected void loadConfigurationFileIntoProperties(String propertyFile...
    method createScheduler (line 206) | private void createScheduler() {
    method createRecorder (line 213) | @SuppressWarnings("unchecked")
    method createCalendar (line 239) | @SuppressWarnings("unchecked")
    method createClient (line 254) | protected void createClient() {
    method createClient (line 263) | protected void createClient(String clientRegion) {
    method awsClient (line 272) | public AWSClient awsClient() {
    method region (line 280) | public String region() {
    method accountName (line 288) | public String accountName() {
    method reportEvent (line 292) | @Override
    method resetEventReport (line 297) | @Override
    method getEventReport (line 302) | @Override
    method exportCredentials (line 327) | public void exportCredentials(String accountKey, String secretKey) {
    method scheduler (line 333) | @Override
    method setScheduler (line 344) | protected void setScheduler(MonkeyScheduler scheduler) {
    method calendar (line 349) | @Override
    method setCalendar (line 360) | protected void setCalendar(MonkeyCalendar calendar) {
    method configuration (line 365) | @Override
    method setConfiguration (line 376) | protected void setConfiguration(MonkeyConfiguration configuration) {
    method cloudClient (line 381) | @Override
    method setCloudClient (line 392) | protected void setCloudClient(CloudClient cloudClient) {
    method recorder (line 397) | @Override
    method setRecorder (line 408) | protected void setRecorder(MonkeyRecorder recorder) {
    method getProperties (line 416) | protected Properties getProperties() {
    method getAwsCredentialsProvider (line 424) | public AWSCredentialsProvider getAwsCredentialsProvider() {
    method getAwsClientConfig (line 432) | public ClientConfiguration getAwsClientConfig() {
    method loadClientClass (line 443) | @SuppressWarnings("rawtypes")
    method factory (line 469) | private <T> T factory(Class<T> implClass) {

FILE: src/main/java/com/netflix/simianarmy/basic/LocalDbRecorder.java
  class LocalDbRecorder (line 49) | public class LocalDbRecorder implements MonkeyRecorder {
    method LocalDbRecorder (line 66) | public LocalDbRecorder(MonkeyConfiguration configuration) {
    method init (line 74) | private synchronized void init() {
    method tempDbFile (line 94) | private static File tempDbFile() {
    method newEvent (line 107) | @Override
    method recordEvent (line 117) | @Override
    method findEvents (line 133) | @Override
    method findEvents (line 160) | @Override
    method findEvents (line 171) | @Override
    method toKey (line 180) | private Fun.Tuple2<Long, Long> toKey(Date date) {
    class MapDbRecorderEvent (line 187) | public static class MapDbRecorderEvent implements MonkeyRecorder.Event...
      method MapDbRecorderEvent (line 214) | public MapDbRecorderEvent(MonkeyType monkeyType, EventType eventType,
      method MapDbRecorderEvent (line 230) | public MapDbRecorderEvent(MonkeyType monkeyType, EventType eventType,
      method id (line 242) | @Override
      method eventTime (line 250) | @Override
      method monkeyType (line 258) | @Override
      method eventType (line 266) | @Override
      method region (line 274) | @Override
      method fields (line 282) | @Override
      method field (line 290) | @Override
      method addField (line 298) | @Override
    method main (line 309) | public static void main(String[] args) {

FILE: src/main/java/com/netflix/simianarmy/basic/calendars/BavarianCalendar.java
  class BavarianCalendar (line 31) | public class BavarianCalendar extends BasicCalendar
    method BavarianCalendar (line 38) | public BavarianCalendar(MonkeyConfiguration cfg)
    method loadHolidays (line 44) | @Override
    method getHolidayWithBridgeDays (line 114) | private Collection<Integer> getHolidayWithBridgeDays(int year, int day...
    method westernEasterDayOfYear (line 140) | protected int westernEasterDayOfYear(int year) {

FILE: src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosEmailNotifier.java
  class BasicChaosEmailNotifier (line 36) | public class BasicChaosEmailNotifier extends ChaosEmailNotifier {
    method BasicChaosEmailNotifier (line 53) | public BasicChaosEmailNotifier(MonkeyConfiguration cfg, AmazonSimpleEm...
    method sendTerminationGlobalNotification (line 68) | @Override
    method sendTerminationNotification (line 86) | @Override
    method getOwnerEmail (line 98) | protected String getOwnerEmail(InstanceGroup group) {
    method buildAndSendEmail (line 121) | public void buildAndSendEmail(String to, InstanceGroup group, String i...
    method buildEmailSubject (line 136) | @Override
    method buildEmailBody (line 153) | public String buildEmailBody(InstanceGroup group, String instanceId, C...
    method getCcAddresses (line 167) | @Override
    method getSourceAddress (line 172) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosInstanceSelector.java
  class BasicChaosInstanceSelector (line 36) | public class BasicChaosInstanceSelector implements ChaosInstanceSelector {
    method logger (line 48) | protected Logger logger() {
    method select (line 53) | @Override
    method selectNInstances (line 64) | private Collection<String> selectNInstances(Collection<String> instanc...
    method selectOneInstance (line 80) | private String selectOneInstance(InstanceGroup group, double probabili...

FILE: src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosMonkey.java
  class BasicChaosMonkey (line 35) | public class BasicChaosMonkey extends ChaosMonkey {
    method BasicChaosMonkey (line 65) | public BasicChaosMonkey(ChaosMonkey.Context ctx) {
    method doMonkeyBusiness (line 103) | @Override
    method pickChaosType (line 133) | private ChaosType pickChaosType(CloudClient cloudClient, String instan...
    method terminateNow (line 154) | @Override
    method reportEventForSummary (line 188) | private void reportEventForSummary(EventTypes eventType, InstanceGroup...
    method handleTerminationError (line 200) | protected void handleTerminationError(String instance, Throwable e) {
    method recordTermination (line 206) | @Override
    method getPreviousTerminationCount (line 217) | @Override
    method createEvent (line 226) | private Event createEvent(EventTypes chaosTermination, InstanceGroup g...
    method getEffectiveProbability (line 239) | protected double getEffectiveProbability(InstanceGroup group) {
    method getEffectiveProbabilityFromCfg (line 259) | protected double getEffectiveProbabilityFromCfg(InstanceGroup group) {
    method getNumFromCfgOrDefault (line 280) | protected double getNumFromCfgOrDefault(InstanceGroup group, String pr...
    method getBoolFromCfgOrDefault (line 286) | protected boolean getBoolFromCfgOrDefault(InstanceGroup group, String ...
    method getLastOptInMilliseconds (line 298) | protected long getLastOptInMilliseconds(InstanceGroup group) {
    method noTerminationInLastWindow (line 304) | private boolean noTerminationInLastWindow(InstanceGroup group, int man...
    method isGroupEnabled (line 328) | protected boolean isGroupEnabled(InstanceGroup group) {
    method isChaosMonkeyEnabled (line 341) | private boolean isChaosMonkeyEnabled() {
    method findInstanceGroup (line 350) | private InstanceGroup findInstanceGroup(String type, String name) {
    method terminateInstance (line 362) | protected Event terminateInstance(InstanceGroup group, String inst, Ch...
    method isMaxTerminationCountExceeded (line 400) | protected boolean isMaxTerminationCountExceeded(InstanceGroup group) {
    method sendTerminationNotification (line 430) | @Override
    method getChaosTypes (line 452) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/chaos/BasicInstanceGroup.java
  class BasicInstanceGroup (line 31) | public class BasicInstanceGroup implements InstanceGroup {
    method BasicInstanceGroup (line 55) | public BasicInstanceGroup(String name, GroupType type, String region, ...
    method type (line 65) | public GroupType type() {
    method name (line 70) | public String name() {
    method region (line 75) | public String region() {
    method tags (line 80) | public List<TagDescription> tags() {
    method instances (line 88) | @Override
    method addInstance (line 94) | @Override
    method copyAs (line 100) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/chaos/CloudFormationChaosMonkey.java
  class CloudFormationChaosMonkey (line 28) | public class CloudFormationChaosMonkey extends BasicChaosMonkey {
    method CloudFormationChaosMonkey (line 35) | public CloudFormationChaosMonkey(Context ctx) {
    method isGroupEnabled (line 42) | @Override
    method terminateInstance (line 51) | @Override
    method isMaxTerminationCountExceeded (line 60) | @Override
    method getEffectiveProbability (line 69) | @Override
    method getLastOptInMilliseconds (line 82) | @Override
    method noSuffixInstanceGroup (line 92) | public InstanceGroup noSuffixInstanceGroup(InstanceGroup group) {

FILE: src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityEmailBuilder.java
  class BasicConformityEmailBuilder (line 34) | public class BasicConformityEmailBuilder extends ConformityEmailBuilder {
    method setEmailToClusters (line 42) | @Override
    method getHeader (line 53) | @Override
    method getEntryTable (line 61) | @Override
    method getFooter (line 76) | @Override
    method getClusterUrl (line 86) | protected String getClusterUrl(Cluster cluster) {
    method getClusterDisplay (line 95) | protected String getClusterDisplay(Cluster cluster) {
    method getTableColumns (line 103) | protected String[] getTableColumns() {
    method getClusterRow (line 113) | protected String getClusterRow(Cluster cluster, Conformity conformity) {

FILE: src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityMonkey.java
  class BasicConformityMonkey (line 42) | public class BasicConformityMonkey extends ConformityMonkey {
    method BasicConformityMonkey (line 94) | public BasicConformityMonkey(Context ctx) {
    method doMonkeyBusiness (line 109) | @Override
    method addCluster (line 182) | private static void addCluster(Map<String, Collection<Cluster>> map, C...
    method sendConformitySummaryEmail (line 194) | protected void sendConformitySummaryEmail() {
    method appendSummary (line 214) | private void appendSummary(StringBuilder message, String summaryName,
    method getSummaryEmailSubject (line 235) | protected String getSummaryEmailSubject() {
    method isConformityMonkeyEnabled (line 239) | private boolean isConformityMonkeyEnabled() {

FILE: src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityMonkeyContext.java
  class BasicConformityMonkeyContext (line 62) | public class BasicConformityMonkeyContext extends BasicSimianArmyContext...
    method BasicConformityMonkeyContext (line 95) | public BasicConformityMonkeyContext() {
    method getConformityEmailNotifierContext (line 194) | public ConformityEmailNotifier.Context getConformityEmailNotifierConte...
    method clusterCrawler (line 248) | @Override
    method ruleEngine (line 253) | @Override
    method emailNotifier (line 259) | @Override
    method regions (line 264) | @Override
    method isLeashed (line 269) | @Override
    method clusterTracker (line 274) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorEmailBuilder.java
  class BasicJanitorEmailBuilder (line 32) | public class BasicJanitorEmailBuilder extends JanitorEmailBuilder {
    method setEmailToResources (line 41) | @Override
    method getHeader (line 47) | @Override
    method getEntryTable (line 57) | @Override
    method getFooter (line 68) | @Override
    method getResourceUrl (line 78) | protected String getResourceUrl(Resource resource) {
    method getResourceDisplay (line 87) | protected String getResourceDisplay(Resource resource) {
    method getJanitorResourceUrl (line 96) | protected String getJanitorResourceUrl(Resource resource) {
    method getTableColumns (line 104) | protected String[] getTableColumns() {
    method getResourceRow (line 113) | protected String getResourceRow(Resource resource) {

FILE: src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorMonkey.java
  class BasicJanitorMonkey (line 37) | public class BasicJanitorMonkey extends JanitorMonkey {
    method BasicJanitorMonkey (line 77) | public BasicJanitorMonkey(Context ctx) {
    method doMonkeyBusiness (line 94) | @Override
    method optInResource (line 151) | @Override
    method optOutResource (line 156) | @Override
    method optInResource (line 161) | @Override
    method optOutResource (line 166) | @Override
    method optInOrOutResource (line 171) | private Event optInOrOutResource(String resourceId, boolean optIn, Str...
    method sendJanitorSummaryEmail (line 194) | protected void sendJanitorSummaryEmail() {
    method appendSummary (line 216) | private void appendSummary(StringBuilder message, String summaryName,
    method printResources (line 223) | private String printResources(Collection<Resource> resources) {
    method getSummaryEmailSubject (line 241) | protected String getSummaryEmailSubject() {
    method handleCleanupError (line 253) | protected void handleCleanupError(Resource resource, Throwable e) {
    method isJanitorMonkeyEnabled (line 260) | private boolean isJanitorMonkeyEnabled() {
    method getMonkeyRuns (line 269) | @Monitor(name="runs", type=DataSourceType.COUNTER)
    method getMonkeyErrors (line 274) | @Monitor(name="errors", type=DataSourceType.GAUGE)
    method getMonkeyRunning (line 279) | @Monitor(name="running", type=DataSourceType.GAUGE)

FILE: src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorMonkeyContext.java
  class BasicJanitorMonkeyContext (line 58) | public class BasicJanitorMonkeyContext extends BasicSimianArmyContext im...
    method BasicJanitorMonkeyContext (line 92) | public BasicJanitorMonkeyContext() {
    method createJanitorRuleEngine (line 161) | protected JanitorRuleEngine createJanitorRuleEngine() {
    method getASGJanitor (line 174) | private ASGJanitor getASGJanitor() {
    method getInstanceJanitor (line 228) | private InstanceJanitor getInstanceJanitor() {
    method getEBSVolumeJanitor (line 266) | private EBSVolumeJanitor getEBSVolumeJanitor() {
    method getEBSSnapshotJanitor (line 304) | private EBSSnapshotJanitor getEBSSnapshotJanitor() {
    method getLaunchConfigJanitor (line 338) | private LaunchConfigJanitor getLaunchConfigJanitor() {
    method getImageJanitor (line 370) | private ImageJanitor getImageJanitor() {
    method getELBJanitor (line 406) | private ELBJanitor getELBJanitor() {
    method createEddaClient (line 428) | private EddaClient createEddaClient() {
    method getEnabledResourceSet (line 435) | private Set<String> getEnabledResourceSet() {
    method getUntaggedRuleResourceSet (line 446) | private Set<String> getUntaggedRuleResourceSet() {
    method getPropertySet (line 459) | private Set<String> getPropertySet(String property) {
    method getJanitorEmailNotifierContext (line 470) | public JanitorEmailNotifier.Context getJanitorEmailNotifierContext() {
    method janitors (line 525) | @Override
    method emailNotifier (line 531) | @Override
    method resourceTracker (line 536) | @Override
    class BasicJanitorContext (line 543) | public static class BasicJanitorContext implements AbstractJanitor.Con...
      method BasicJanitorContext (line 561) | public BasicJanitorContext(String region, JanitorRuleEngine ruleEngi...
      method region (line 573) | @Override
      method configuration (line 578) | @Override
      method calendar (line 583) | @Override
      method janitorRuleEngine (line 588) | @Override
      method janitorCrawler (line 593) | @Override
      method janitorResourceTracker (line 598) | @Override
      method recorder (line 603) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorRuleEngine.java
  class BasicJanitorRuleEngine (line 35) | public class BasicJanitorRuleEngine implements JanitorRuleEngine {
    method BasicJanitorRuleEngine (line 49) | public BasicJanitorRuleEngine() {
    method isValid (line 65) | @Override
    method addRule (line 107) | @Override
    method addExclusionRule (line 114) | @Override
    method getRules (line 121) | @Override
    method getExclusionRules (line 128) | @Override

FILE: src/main/java/com/netflix/simianarmy/basic/janitor/BasicVolumeTaggingMonkeyContext.java
  class BasicVolumeTaggingMonkeyContext (line 30) | public class BasicVolumeTaggingMonkeyContext extends BasicSimianArmyCont...
    method BasicVolumeTaggingMonkeyContext (line 37) | public BasicVolumeTaggingMonkeyContext() {
    method awsClients (line 45) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/BlockAllNetworkTrafficChaosType.java
  class BlockAllNetworkTrafficChaosType (line 35) | public class BlockAllNetworkTrafficChaosType extends ChaosType {
    method BlockAllNetworkTrafficChaosType (line 47) | public BlockAllNetworkTrafficChaosType(MonkeyConfiguration config) {
    method canApply (line 56) | @Override
    method apply (line 72) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/BurnCpuChaosType.java
  class BurnCpuChaosType (line 27) | public class BurnCpuChaosType extends ScriptChaosType {
    method BurnCpuChaosType (line 34) | public BurnCpuChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/BurnIoChaosType.java
  class BurnIoChaosType (line 30) | public class BurnIoChaosType extends ScriptChaosType {
    method BurnIoChaosType (line 63) | public BurnIoChaosType(MonkeyConfiguration config) {
    method canApply (line 67) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosCrawler.java
  type ChaosCrawler (line 29) | public interface ChaosCrawler {
    type InstanceGroup (line 34) | public interface InstanceGroup {
      method type (line 41) | GroupType type();
      method name (line 48) | String name();
      method region (line 55) | String region();
      method tags (line 62) | List<TagDescription> tags();
      method instances (line 69) | List<String> instances();
      method addInstance (line 77) | void addInstance(String instance);
      method copyAs (line 87) | InstanceGroup copyAs(String name);
    method groupTypes (line 95) | EnumSet<?> groupTypes();
    method groups (line 102) | List<InstanceGroup> groups();
    method groups (line 111) | List<InstanceGroup> groups(String... names);

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosEmailNotifier.java
  class ChaosEmailNotifier (line 27) | public abstract class ChaosEmailNotifier extends AWSEmailNotifier {
    method ChaosEmailNotifier (line 35) | public ChaosEmailNotifier(AmazonSimpleEmailServiceClient sesClient) {
    method sendTerminationNotification (line 46) | public abstract void sendTerminationNotification(InstanceGroup group, ...
    method sendTerminationGlobalNotification (line 55) | public abstract void sendTerminationGlobalNotification(InstanceGroup g...

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosInstance.java
  class ChaosInstance (line 30) | public class ChaosInstance {
    method ChaosInstance (line 48) | public ChaosInstance(CloudClient cloudClient, String instanceId, SshCo...
    method getSshConfig (line 59) | public SshConfig getSshConfig() {
    method getCloudClient (line 68) | public CloudClient getCloudClient() {
    method getInstanceId (line 77) | public String getInstanceId() {
    method canConnectSsh (line 93) | public boolean canConnectSsh(ChaosInstance instance) {
    method connectSsh (line 117) | public SshClient connectSsh() {

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosInstanceSelector.java
  type ChaosInstanceSelector (line 27) | public interface ChaosInstanceSelector {
    method select (line 54) | Collection<String> select(InstanceGroup group, double probability);

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosMonkey.java
  class ChaosMonkey (line 34) | public abstract class ChaosMonkey extends Monkey {
    type Context (line 39) | public interface Context extends Monkey.Context {
      method configuration (line 46) | MonkeyConfiguration configuration();
      method chaosCrawler (line 53) | ChaosCrawler chaosCrawler();
      method chaosInstanceSelector (line 60) | ChaosInstanceSelector chaosInstanceSelector();
      method chaosEmailNotifier (line 67) | ChaosEmailNotifier chaosEmailNotifier();
    method ChaosMonkey (line 79) | public ChaosMonkey(Context ctx) {
    type Type (line 87) | public enum Type implements MonkeyType {
    type EventTypes (line 96) | public enum EventTypes implements EventType {
    method type (line 103) | @Override
    method context (line 109) | @Override
    method doMonkeyBusiness (line 115) | @Override
    method getPreviousTerminationCount (line 126) | public abstract int getPreviousTerminationCount(ChaosCrawler.InstanceG...
    method recordTermination (line 138) | public abstract Event recordTermination(ChaosCrawler.InstanceGroup gro...
    method terminateNow (line 150) | public abstract Event terminateNow(String type, String name, ChaosType...
    method sendTerminationNotification (line 163) | public abstract void sendTerminationNotification(ChaosCrawler.Instance...
    method getChaosTypes (line 169) | public abstract List<ChaosType> getChaosTypes();

FILE: src/main/java/com/netflix/simianarmy/chaos/ChaosType.java
  class ChaosType (line 31) | public abstract class ChaosType {
    method ChaosType (line 58) | protected ChaosType(MonkeyConfiguration config, String key) {
    method getEnabledDefault (line 72) | protected boolean getEnabledDefault() {
    method getConfigurationPrefix (line 79) | protected String getConfigurationPrefix() {
    method getKey (line 86) | public String getKey() {
    method canApply (line 96) | public boolean canApply(ChaosInstance instance) {
    method isEnabled (line 103) | public boolean isEnabled() {
    method apply (line 110) | public abstract void apply(ChaosInstance instance);
    method parse (line 115) | public static ChaosType parse(List<ChaosType> all, String chaosTypeNam...
    method isBurnMoneyEnabled (line 128) | protected boolean isBurnMoneyEnabled() {
    method isRootVolumeEbs (line 138) | protected boolean isRootVolumeEbs(ChaosInstance instance) {

FILE: src/main/java/com/netflix/simianarmy/chaos/DetachVolumesChaosType.java
  class DetachVolumesChaosType (line 35) | public class DetachVolumesChaosType extends ChaosType {
    method DetachVolumesChaosType (line 45) | public DetachVolumesChaosType(MonkeyConfiguration config) {
    method canApply (line 52) | @Override
    method apply (line 69) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/FailDnsChaosType.java
  class FailDnsChaosType (line 25) | public class FailDnsChaosType extends ScriptChaosType {
    method FailDnsChaosType (line 32) | public FailDnsChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/FailDynamoDbChaosType.java
  class FailDynamoDbChaosType (line 25) | public class FailDynamoDbChaosType extends ScriptChaosType {
    method FailDynamoDbChaosType (line 32) | public FailDynamoDbChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/FailEc2ChaosType.java
  class FailEc2ChaosType (line 25) | public class FailEc2ChaosType extends ScriptChaosType {
    method FailEc2ChaosType (line 32) | public FailEc2ChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/FailS3ChaosType.java
  class FailS3ChaosType (line 25) | public class FailS3ChaosType extends ScriptChaosType {
    method FailS3ChaosType (line 32) | public FailS3ChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/FillDiskChaosType.java
  class FillDiskChaosType (line 28) | public class FillDiskChaosType extends ScriptChaosType {
    method FillDiskChaosType (line 46) | public FillDiskChaosType(MonkeyConfiguration config) {
    method canApply (line 50) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/KillProcessesChaosType.java
  class KillProcessesChaosType (line 27) | public class KillProcessesChaosType extends ScriptChaosType {
    method KillProcessesChaosType (line 34) | public KillProcessesChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/NetworkCorruptionChaosType.java
  class NetworkCorruptionChaosType (line 25) | public class NetworkCorruptionChaosType extends ScriptChaosType {
    method NetworkCorruptionChaosType (line 32) | public NetworkCorruptionChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/NetworkLatencyChaosType.java
  class NetworkLatencyChaosType (line 25) | public class NetworkLatencyChaosType extends ScriptChaosType {
    method NetworkLatencyChaosType (line 32) | public NetworkLatencyChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/NetworkLossChaosType.java
  class NetworkLossChaosType (line 25) | public class NetworkLossChaosType extends ScriptChaosType {
    method NetworkLossChaosType (line 32) | public NetworkLossChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/NullRouteChaosType.java
  class NullRouteChaosType (line 30) | public class NullRouteChaosType extends ScriptChaosType {
    method NullRouteChaosType (line 37) | public NullRouteChaosType(MonkeyConfiguration config) {

FILE: src/main/java/com/netflix/simianarmy/chaos/ScriptChaosType.java
  class ScriptChaosType (line 34) | public abstract class ScriptChaosType extends ChaosType {
    method ScriptChaosType (line 46) | public ScriptChaosType(MonkeyConfiguration config, String key) {
    method canApply (line 53) | @Override
    method apply (line 71) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/ShutdownInstanceChaosType.java
  class ShutdownInstanceChaosType (line 28) | public class ShutdownInstanceChaosType extends ChaosType {
    method ShutdownInstanceChaosType (line 35) | public ShutdownInstanceChaosType(MonkeyConfiguration config) {
    method apply (line 42) | @Override
    method getEnabledDefault (line 53) | @Override

FILE: src/main/java/com/netflix/simianarmy/chaos/SshConfig.java
  class SshConfig (line 34) | public class SshConfig {
    method SshConfig (line 49) | public SshConfig(MonkeyConfiguration config) {
    method getCredentials (line 87) | public LoginCredentials getCredentials() {
    method isEnabled (line 96) | public boolean isEnabled() {

FILE: src/main/java/com/netflix/simianarmy/client/MonkeyRestClient.java
  class MonkeyRestClient (line 39) | public abstract class MonkeyRestClient {
    method MonkeyRestClient (line 50) | public MonkeyRestClient(int timeout, int maxRetries, int retryInterval) {
    method getJsonNodeFromUrl (line 70) | public JsonNode getJsonNodeFromUrl(String url) throws IOException {
    method getBaseUrl (line 109) | public abstract String getBaseUrl(String region);
    class DataReadException (line 111) | public static class DataReadException extends RuntimeException {
      method DataReadException (line 112) | public DataReadException(int code, String url, String jsonContent) {

FILE: src/main/java/com/netflix/simianarmy/client/aws/AWSClient.java
  class AWSClient (line 77) | public class AWSClient implements CloudClient {
    method AWSClient (line 131) | public AWSClient(String region) {
    method AWSClient (line 145) | public AWSClient(String region, AWSCredentialsProvider awsCredentialsP...
    method AWSClient (line 159) | public AWSClient(String region, ClientConfiguration awsClientConfig) {
    method AWSClient (line 175) | public AWSClient(String region, AWSCredentialsProvider awsCredentialsP...
    method region (line 187) | public String region() {
    method accountName (line 197) | public String accountName() {
    method ec2Client (line 206) | protected AmazonEC2 ec2Client() {
    method asgClient (line 230) | protected AmazonAutoScalingClient asgClient() {
    method elbClient (line 254) | protected AmazonElasticLoadBalancingClient elbClient() {
    method route53Client (line 278) | protected AmazonRoute53Client route53Client() {
    method sdbClient (line 302) | public AmazonSimpleDB sdbClient() {
    method describeAutoScalingGroups (line 332) | public List<AutoScalingGroup> describeAutoScalingGroups() {
    method describeAutoScalingGroups (line 342) | public List<AutoScalingGroup> describeAutoScalingGroups(String... name...
    method describeElasticLoadBalancers (line 375) | public List<LoadBalancerDescription> describeElasticLoadBalancers(Stri...
    method describeElasticLoadBalancerAttributes (line 396) | public LoadBalancerAttributes describeElasticLoadBalancerAttributes(St...
    method describeElasticLoadBalancerTags (line 412) | public List<TagDescription> describeElasticLoadBalancerTags(String nam...
    method describeAutoScalingInstances (line 427) | public List<AutoScalingInstanceDetails> describeAutoScalingInstances(S...
    method describeInstances (line 461) | public List<Instance> describeInstances(String... instanceIds) {
    method describeLaunchConfigurations (line 490) | public List<LaunchConfiguration> describeLaunchConfigurations(String.....
    method deleteAutoScalingGroup (line 517) | @Override
    method deleteLaunchConfiguration (line 533) | @Override
    method deleteImage (line 545) | @Override
    method deleteVolume (line 556) | @Override
    method deleteSnapshot (line 566) | @Override
    method deleteElasticLoadBalancer (line 576) | @Override
    method deleteDNSRecord (line 586) | @Override
    method terminateInstance (line 619) | @Override
    method setInstanceSecurityGroups (line 634) | public void setInstanceSecurityGroups(String instanceId, List<String> ...
    method describeVolumes (line 656) | public List<Volume> describeVolumes(String... volumeIds) {
    method describeSnapshots (line 681) | public List<Snapshot> describeSnapshots(String... snapshotIds) {
    method createTagsForResources (line 702) | @Override
    method describeImages (line 723) | public List<Image> describeImages(String... imageIds) {
    method detachVolume (line 742) | @Override
    method listAttachedVolumes (line 760) | @Override
    method describeSecurityGroups (line 802) | public List<SecurityGroup> describeSecurityGroups(String... groupNames) {
    method createSecurityGroup (line 831) | public String createSecurityGroup(String instanceId, String name, Stri...
    method describeInstance (line 852) | public Instance describeInstance(String instanceId) {
    method getJcloudsComputeService (line 864) | @Override
    method getJcloudsId (line 896) | @Override
    method connectSsh (line 901) | @Override
    method getJcloudsNode (line 918) | private NodeMetadata getJcloudsNode(ComputeService computeService, Str...
    method findSecurityGroup (line 944) | @Override
    method getVpcId (line 971) | String getVpcId(String instanceId) {
    method canChangeInstanceSecurityGroups (line 983) | @Override

FILE: src/main/java/com/netflix/simianarmy/client/aws/chaos/ASGChaosCrawler.java
  class ASGChaosCrawler (line 39) | public class ASGChaosCrawler implements ChaosCrawler {
    type Types (line 52) | public enum Types implements GroupType {
    method ASGChaosCrawler (line 67) | public ASGChaosCrawler(AWSClient awsClient) {
    method groupTypes (line 72) | @Override
    method groups (line 78) | @Override
    method groups (line 83) | @Override
    method getInstanceGroup (line 106) | protected InstanceGroup getInstanceGroup(AutoScalingGroup asg, double ...
    method findAggressionCoefficient (line 130) | protected double findAggressionCoefficient(AutoScalingGroup asg) {

FILE: src/main/java/com/netflix/simianarmy/client/aws/chaos/FilteringChaosCrawler.java
  class FilteringChaosCrawler (line 31) | public class FilteringChaosCrawler implements ChaosCrawler {
    method FilteringChaosCrawler (line 36) | public FilteringChaosCrawler(ChaosCrawler crawler, Predicate<? super I...
    method groupTypes (line 42) | @Override
    method groups (line 48) | @Override
    method groups (line 54) | @Override
    method filter (line 65) | protected List<InstanceGroup> filter(List<InstanceGroup> list) {

FILE: src/main/java/com/netflix/simianarmy/client/aws/chaos/TagPredicate.java
  class TagPredicate (line 28) | public class TagPredicate implements Predicate<ChaosCrawler.InstanceGrou...
    method TagPredicate (line 32) | public TagPredicate(String key, String value) {
    method apply (line 37) | @Override

FILE: src/main/java/com/netflix/simianarmy/client/edda/EddaClient.java
  class EddaClient (line 30) | public class EddaClient extends MonkeyRestClient {
    method EddaClient (line 41) | public EddaClient(int timeout, int maxRetries, int retryInterval, Monk...
    method getBaseUrl (line 46) | @Override

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/PropertyBasedTerminationStrategy.java
  class PropertyBasedTerminationStrategy (line 32) | public class PropertyBasedTerminationStrategy implements TerminationStra...
    method PropertyBasedTerminationStrategy (line 41) | public PropertyBasedTerminationStrategy(MonkeyConfiguration config) {
    method terminate (line 48) | @Override
    method getPropertyName (line 54) | public String getPropertyName() {
    method getPropertyValue (line 58) | public String getPropertyValue() {

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/TerminationStrategy.java
  type TerminationStrategy (line 27) | public interface TerminationStrategy {
    method terminate (line 31) | void terminate(VirtualMachine virtualMachine) throws RemoteException;

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/VSphereClient.java
  class VSphereClient (line 33) | public class VSphereClient extends AWSClient {
    method VSphereClient (line 42) | public VSphereClient(TerminationStrategy terminationStrategy, VSphereS...
    method describeAutoScalingGroups (line 48) | @Override
    method terminateInstance (line 76) | @Override

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/VSphereContext.java
  class VSphereContext (line 26) | public class VSphereContext extends BasicChaosMonkeyContext {
    method createClient (line 27) | @Override

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/VSphereGroups.java
  class VSphereGroups (line 33) | class VSphereGroups {
    method asList (line 39) | public List<AutoScalingGroup> asList() {
    method addInstance (line 53) | public void addInstance(final String instanceId, final String groupNam...

FILE: src/main/java/com/netflix/simianarmy/client/vsphere/VSphereServiceConnection.java
  class VSphereServiceConnection (line 42) | public class VSphereServiceConnection {
    method VSphereServiceConnection (line 61) | public VSphereServiceConnection(MonkeyConfiguration config) {
    method disconnect (line 68) | public void disconnect() {
    method connect (line 76) | public void connect() throws AmazonServiceException {
    method getVirtualMachineById (line 91) | public VirtualMachine getVirtualMachineById(String instanceId) throws ...
    method describeVirtualMachines (line 104) | public VirtualMachine[] describeVirtualMachines() throws AmazonService...
    method getInventoryNavigator (line 127) | protected InventoryNavigator getInventoryNavigator() {
    method getUsername (line 131) | public String getUsername() {
    method getPassword (line 134) | public String getPassword() {
    method getUrl (line 137) | public String getUrl() {

FILE: src/main/java/com/netflix/simianarmy/conformity/AutoScalingGroup.java
  class AutoScalingGroup (line 29) | public class AutoScalingGroup {
    method AutoScalingGroup (line 41) | public AutoScalingGroup(String name, String... instances) {
    method getName (line 55) | public String getName() {
    method getInstances (line 64) | public Collection<String> getInstances() {
    method isSuspended (line 72) | public boolean isSuspended() {
    method setSuspended (line 80) | public void setSuspended(boolean suspended) {

FILE: src/main/java/com/netflix/simianarmy/conformity/Cluster.java
  class Cluster (line 39) | public class Cluster {
    method Cluster (line 68) | public Cluster(String name, String region, AutoScalingGroup... autoSca...
    method Cluster (line 86) | public Cluster(String name, String region, Set<String> soloInstances) {
    method getName (line 102) | public String getName() {
    method getRegion (line 111) | public String getRegion() {
    method getAutoScalingGroups (line 120) | public Collection<AutoScalingGroup> getAutoScalingGroups() {
    method getOwnerEmail (line 129) | public String getOwnerEmail() {
    method setOwnerEmail (line 138) | public void setOwnerEmail(String ownerEmail) {
    method getUpdateTime (line 147) | public Date getUpdateTime() {
    method setUpdateTime (line 156) | public void setUpdateTime(Date updateTime) {
    method getConformties (line 165) | public Collection<Conformity> getConformties() {
    method getConformity (line 176) | public Conformity getConformity(ConformityRule rule) {
    method updateConformity (line 189) | public Cluster updateConformity(Conformity conformity) {
    method clearConformities (line 198) | public void clearConformities() {
    method isConforming (line 209) | public boolean isConforming() {
    method setConforming (line 220) | public void setConforming(boolean conforming) {
    method getExcludedRules (line 229) | public Collection<String> getExcludedRules() {
    method excludeRules (line 240) | public Cluster excludeRules(String... ruleIds) {
    method isOptOutOfConformity (line 253) | public boolean isOptOutOfConformity() {
    method setOptOutOfConformity (line 262) | public void setOptOutOfConformity(boolean optOutOfConformity) {
    method getFieldToValueMap (line 271) | public Map<String, String> getFieldToValueMap() {
    method parseFieldToValueMap (line 294) | public static Cluster parseFieldToValueMap(Map<String, String> fieldTo...
    method putToMapIfNotNull (line 310) | private static void putToMapIfNotNull(Map<String, String> map, String ...
    method getSoloInstances (line 318) | public Set<String> getSoloInstances() {

FILE: src/main/java/com/netflix/simianarmy/conformity/ClusterCrawler.java
  type ClusterCrawler (line 25) | public interface ClusterCrawler {
    method clusters (line 35) | List<Cluster> clusters(String... clusterNames);
    method getOwnerEmailForCluster (line 43) | String getOwnerEmailForCluster(Cluster cluster);
    method updateExcludedConformityRules (line 49) | void updateExcludedConformityRules(Cluster cluster);

FILE: src/main/java/com/netflix/simianarmy/conformity/Conformity.java
  class Conformity (line 29) | public class Conformity {
    method Conformity (line 42) | public Conformity(String ruleId, Collection<String> failedComponents) {
    method getRuleId (line 56) | public String getRuleId() {
    method getFailedComponents (line 65) | public Collection<String> getFailedComponents() {

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityClusterTracker.java
  type ConformityClusterTracker (line 25) | public interface ConformityClusterTracker {
    method addOrUpdate (line 32) | void addOrUpdate(Cluster cluster);
    method getAllClusters (line 41) | List<Cluster> getAllClusters(String... regions);
    method getNonconformingClusters (line 49) | List<Cluster> getNonconformingClusters(String... regions);
    method getCluster (line 57) | Cluster getCluster(String name, String region);
    method deleteClusters (line 65) | void deleteClusters(Cluster... clusters);

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityEmailBuilder.java
  class ConformityEmailBuilder (line 26) | public abstract class ConformityEmailBuilder extends AbstractEmailBuilder {
    method setEmailToClusters (line 34) | public abstract void setEmailToClusters(Map<String, Collection<Cluster...

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityEmailNotifier.java
  class ConformityEmailNotifier (line 36) | public class ConformityEmailNotifier  extends AWSEmailNotifier {
    type Context (line 56) | public interface Context {
      method sesClient (line 61) | AmazonSimpleEmailServiceClient sesClient();
      method openHour (line 68) | int openHour();
      method closeHour (line 75) | int closeHour();
      method sourceEmail (line 81) | String sourceEmail();
      method defaultEmail (line 87) | String defaultEmail();
      method regions (line 93) | Collection<String> regions();
      method clusterTracker (line 98) | ConformityClusterTracker clusterTracker();
      method emailBuilder (line 103) | ConformityEmailBuilder emailBuilder();
      method ccEmails (line 108) | String[] ccEmails();
      method rules (line 114) | Collection<ConformityRule> rules();
    method ConformityEmailNotifier (line 121) | public ConformityEmailNotifier(Context ctx) {
    method sendNotifications (line 147) | public void sendNotifications() {
    method buildEmailSubject (line 202) | @Override
    method getCcAddresses (line 207) | @Override
    method getSourceAddress (line 212) | @Override
    method validateEmails (line 217) | private void validateEmails() {
    method putEmailAndCluster (line 228) | private void putEmailAndCluster(Map<String, Collection<Cluster>> map, ...

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityMonkey.java
  class ConformityMonkey (line 29) | public abstract class ConformityMonkey extends Monkey {
    type Context (line 34) | public interface Context extends Monkey.Context {
      method configuration (line 41) | MonkeyConfiguration configuration();
      method clusterCrawler (line 47) | ClusterCrawler clusterCrawler();
      method ruleEngine (line 53) | ConformityRuleEngine ruleEngine();
      method emailNotifier (line 60) | ConformityEmailNotifier emailNotifier();
      method regions (line 66) | Collection<String> regions();
      method clusterTracker (line 72) | ConformityClusterTracker clusterTracker();
      method isLeashed (line 79) | boolean isLeashed();
    method ConformityMonkey (line 91) | public ConformityMonkey(Context ctx) {
    type Type (line 99) | public enum Type implements MonkeyType {
    method type (line 105) | @Override
    method context (line 111) | @Override
    method doMonkeyBusiness (line 117) | @Override

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityRule.java
  type ConformityRule (line 24) | public interface ConformityRule {
    method check (line 33) | Conformity check(Cluster cluster);
    method getName (line 40) | String getName();
    method getNonconformingReason (line 46) | String getNonconformingReason();

FILE: src/main/java/com/netflix/simianarmy/conformity/ConformityRuleEngine.java
  class ConformityRuleEngine (line 31) | public class ConformityRuleEngine {
    method check (line 44) | public boolean check(Cluster cluster) {
    method addRule (line 74) | public ConformityRuleEngine addRule(ConformityRule rule) {
    method rules (line 84) | public Collection<ConformityRule> rules() {

FILE: src/main/java/com/netflix/simianarmy/janitor/AbstractJanitor.java
  class AbstractJanitor (line 49) | public abstract class AbstractJanitor implements Janitor, DryRunnableJan...
    method getRegion (line 60) | public String getRegion() {
    method setLeashed (line 110) | protected void setLeashed(boolean isLeashed) {
    type Context (line 117) | public interface Context {
      method region (line 123) | String region();
      method configuration (line 130) | MonkeyConfiguration configuration();
      method calendar (line 137) | MonkeyCalendar calendar();
      method janitorRuleEngine (line 143) | JanitorRuleEngine janitorRuleEngine();
      method janitorCrawler (line 150) | JanitorCrawler janitorCrawler();
      method janitorResourceTracker (line 157) | JanitorResourceTracker janitorResourceTracker();
      method recorder (line 164) | MonkeyRecorder recorder();
    method AbstractJanitor (line 172) | public AbstractJanitor(Context ctx, ResourceType resourceType) {
    method getResourceType (line 202) | @Override
    method prepareToRun (line 221) | public void prepareToRun() {
    method markResources (line 233) | @Override
    method getTrackedMarkedResources (line 295) | protected Map<String, Resource> getTrackedMarkedResources() {
    method cleanupResources (line 306) | @Override
    method canClean (line 385) | protected boolean canClean(Resource resource, Date now) {
    method postMark (line 398) | protected abstract void postMark(Resource resource);
    method cleanup (line 404) | protected abstract void cleanup(Resource resource);
    method postCleanup (line 410) | protected abstract void postCleanup(Resource resource);
    method getMarkedResources (line 413) | public Collection<Resource> getMarkedResources() {
    method getUnmarkedResources (line 418) | public Collection<Resource> getUnmarkedResources() {
    method getCleanedResources (line 423) | public Collection<Resource> getCleanedResources() {
    method getFailedToCleanResources (line 428) | public Collection<Resource> getFailedToCleanResources() {
    method unmarkUserTerminatedResources (line 432) | private void unmarkUserTerminatedResources(List<Resource> crawledResou...
    method getResourcesCleanedCount (line 453) | @Monitor(name="cleanedResourcesCount", type=DataSourceType.GAUGE)
    method getMarkedResourcesCount (line 458) | @Monitor(name="markedResourcesCount", type=DataSourceType.GAUGE)
    method getFailedToCleanResourcesCount (line 463) | @Monitor(name="failedToCleanResourcesCount", type=DataSourceType.GAUGE)
    method getUnmarkedResourcesCount (line 468) | @Monitor(name="unmarkedResourcesCount", type=DataSourceType.GAUGE)
    method getCheckedResourcesCount (line 473) | @Monitor(name="checkedResourcesCount", type=DataSourceType.GAUGE)
    method skippedVanishedOrValidResources (line 478) | @Monitor(name="skippedVanishedOrValidResources", type = DataSourceType...
    method getCleanupDryRunFailureCount (line 483) | public Counter getCleanupDryRunFailureCount() {

FILE: src/main/java/com/netflix/simianarmy/janitor/DryRunnableJanitor.java
  type DryRunnableJanitor (line 23) | public interface DryRunnableJanitor extends Janitor {
    method cleanupDryRun (line 24) | default void cleanupDryRun(Resource markedResource) throws DryRunnable...

FILE: src/main/java/com/netflix/simianarmy/janitor/DryRunnableJanitorException.java
  class DryRunnableJanitorException (line 21) | public class DryRunnableJanitorException extends Exception {
    method DryRunnableJanitorException (line 22) | public DryRunnableJanitorException(String message) {
    method DryRunnableJanitorException (line 26) | public DryRunnableJanitorException(String message, Throwable cause) {

FILE: src/main/java/com/netflix/simianarmy/janitor/Janitor.java
  type Janitor (line 27) | public interface Janitor {
    method getResourceType (line 33) | ResourceType getResourceType();
    method markResources (line 39) | void markResources();
    method cleanupResources (line 44) | void cleanupResources();

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorCrawler.java
  type JanitorCrawler (line 30) | public interface JanitorCrawler {
    method resourceTypes (line 37) | EnumSet<? extends ResourceType> resourceTypes();
    method resources (line 45) | List<Resource> resources(ResourceType resourceType);
    method resources (line 55) | List<Resource> resources(String... resourceIds);
    method getOwnerEmailForResource (line 62) | String getOwnerEmailForResource(Resource resource);

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorEmailBuilder.java
  class JanitorEmailBuilder (line 27) | public abstract class JanitorEmailBuilder extends AbstractEmailBuilder {
    method setEmailToResources (line 34) | public abstract void setEmailToResources(Map<String, Collection<Resour...

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorEmailNotifier.java
  class JanitorEmailNotifier (line 40) | public class JanitorEmailNotifier extends AWSEmailNotifier {
    type Context (line 66) | public interface Context {
      method sesClient (line 71) | AmazonSimpleEmailServiceClient sesClient();
      method sourceEmail (line 77) | String sourceEmail();
      method defaultEmail (line 83) | String defaultEmail();
      method daysBeforeTermination (line 89) | int daysBeforeTermination();
      method region (line 95) | String region();
      method resourceTracker (line 100) | JanitorResourceTracker resourceTracker();
      method emailBuilder (line 105) | JanitorEmailBuilder emailBuilder();
      method calendar (line 110) | MonkeyCalendar calendar();
      method ccEmails (line 115) | String[] ccEmails();
      method ownerEmailDomain (line 120) | String ownerEmailDomain();
    method JanitorEmailNotifier (line 127) | public JanitorEmailNotifier(Context ctx) {
    method sendNotifications (line 151) | public void sendNotifications() {
    method getMarkedResources (line 208) | protected Collection<Resource> getMarkedResources() {
    method validateEmails (line 212) | private void validateEmails() {
    method buildEmailSubject (line 223) | @Override
    method canNotify (line 234) | protected boolean canNotify(Resource resource) {
    method getInvalidEmailToResources (line 275) | public Map<String, Collection<Resource>> getInvalidEmailToResources() {
    method getCcAddresses (line 279) | @Override
    method getSourceAddress (line 284) | @Override
    method putEmailAndResource (line 289) | private void putEmailAndResource(

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorMonkey.java
  class JanitorMonkey (line 31) | public abstract class JanitorMonkey extends Monkey {
    type Context (line 45) | public interface Context extends Monkey.Context {
      method configuration (line 52) | MonkeyConfiguration configuration();
      method janitors (line 58) | List<AbstractJanitor> janitors();
      method emailNotifier (line 64) | JanitorEmailNotifier emailNotifier();
      method region (line 70) | String region();
      method accountName (line 76) | String accountName();
      method resourceTracker (line 82) | JanitorResourceTracker resourceTracker();
    method JanitorMonkey (line 94) | public JanitorMonkey(Context ctx) {
    type Type (line 102) | public static enum Type implements MonkeyType {
    type EventTypes (line 110) | public enum EventTypes implements EventType {
    method type (line 124) | @Override
    method context (line 130) | @Override
    method doMonkeyBusiness (line 136) | @Override
    method optInResource (line 144) | public abstract Event optInResource(String resourceId);
    method optOutResource (line 151) | public abstract Event optOutResource(String resourceId);
    method optInResource (line 159) | public abstract Event optInResource(String resourceId, String region);
    method optOutResource (line 167) | public abstract Event optOutResource(String resourceId, String region);

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorResourceTracker.java
  type JanitorResourceTracker (line 29) | public interface JanitorResourceTracker {
    method addOrUpdate (line 36) | void addOrUpdate(Resource resource);
    method getResources (line 46) | List<Resource> getResources(ResourceType resourceType, Resource.Cleanu...
    method getResource (line 53) | Resource getResource(String resourceId);
    method getResource (line 61) | Resource getResource(String resourceId, String regionId);

FILE: src/main/java/com/netflix/simianarmy/janitor/JanitorRuleEngine.java
  type JanitorRuleEngine (line 28) | public interface JanitorRuleEngine {
    method isValid (line 38) | boolean isValid(Resource resource);
    method addRule (line 47) | JanitorRuleEngine addRule(Rule rule);
    method addExclusionRule (line 58) | JanitorRuleEngine addExclusionRule(Rule rule);
    method getRules (line 65) | List<Rule> getRules();
    method getExclusionRules (line 72) | List<Rule> getExclusionRules();

FILE: src/main/java/com/netflix/simianarmy/janitor/Rule.java
  type Rule (line 26) | public interface Rule {
    method isValid (line 36) | boolean isValid(Resource resource);

FILE: src/main/java/com/netflix/simianarmy/resources/chaos/ChaosMonkeyResource.java
  class ChaosMonkeyResource (line 62) | @Path("/v1/chaos")
    method ChaosMonkeyResource (line 82) | public ChaosMonkeyResource(ChaosMonkey monkey) {
    method ChaosMonkeyResource (line 89) | public ChaosMonkeyResource() {
    method getChaosEvents (line 113) | @GET
    method addEvent (line 166) | @POST
    method addTerminationEvent (line 210) | private Response.Status addTerminationEvent(String groupType,
    method getStringField (line 248) | private String getStringField(JsonNode input, String field) {

FILE: src/main/java/com/netflix/simianarmy/resources/janitor/JanitorMonkeyResource.java
  class JanitorMonkeyResource (line 46) | @Path("/v1/janitor")
    method JanitorMonkeyResource (line 64) | public JanitorMonkeyResource(JanitorMonkey monkey) {
    method JanitorMonkeyResource (line 68) | public JanitorMonkeyResource() {
    method getJanitorMonkey (line 71) | public JanitorMonkey getJanitorMonkey() {
    method addEventThroughHttpGet (line 89) | @GET @Path("addEvent")
    method addEvent (line 137) | @POST
    method getJanitorStatus (line 183) | @GET
    method optInResource (line 196) | private Response.Status optInResource(String resourceId, boolean optIn...
    method getStringField (line 225) | private String getStringField(JsonNode input, String field) {

FILE: src/main/java/com/netflix/simianarmy/tunable/TunableInstanceGroup.java
  class TunableInstanceGroup (line 33) | public class TunableInstanceGroup extends BasicInstanceGroup {
    method TunableInstanceGroup (line 35) | public TunableInstanceGroup(String name, GroupType type, String region...
    method getAggressionCoefficient (line 44) | public final double getAggressionCoefficient() {
    method setAggressionCoefficient (line 51) | public final void setAggressionCoefficient(double aggressionCoefficien...

FILE: src/main/java/com/netflix/simianarmy/tunable/TunablyAggressiveChaosMonkey.java
  class TunablyAggressiveChaosMonkey (line 29) | public class TunablyAggressiveChaosMonkey extends BasicChaosMonkey {
    method TunablyAggressiveChaosMonkey (line 31) | public TunablyAggressiveChaosMonkey(Context ctx) {
    method getEffectiveProbability (line 43) | @Override

FILE: src/test/java/com/netflix/simianarmy/TestMonkey.java
  class TestMonkey (line 24) | public class TestMonkey extends Monkey {
    method TestMonkey (line 25) | public TestMonkey() {
    type Type (line 29) | public enum Type implements MonkeyType {
    method type (line 33) | public Type type() {
    method doMonkeyBusiness (line 37) | public void doMonkeyBusiness() {
    method testStart (line 41) | @Test
    method testStop (line 46) | @Test

FILE: src/test/java/com/netflix/simianarmy/TestMonkeyContext.java
  class TestMonkeyContext (line 49) | public class TestMonkeyContext implements Monkey.Context {
    method TestMonkeyContext (line 53) | public TestMonkeyContext(MonkeyType monkeyType) {
    method configuration (line 57) | @Override
    method scheduler (line 62) | @Override
    method calendar (line 88) | @Override
    method cloudClient (line 119) | @Override
    method newEvent (line 209) | @Override
    method recordEvent (line 214) | @Override
    method findEvents (line 219) | @Override
    method findEvents (line 224) | @Override
    method findEvents (line 230) | @Override
    method recorder (line 244) | @Override
    method reportEvent (line 249) | @Override
    method resetEventReport (line 254) | @Override
    method getEventReport (line 259) | @Override

FILE: src/test/java/com/netflix/simianarmy/TestMonkeyRunner.java
  class TestMonkeyRunner (line 26) | public class TestMonkeyRunner {
    class MonkeyA (line 29) | private static class MonkeyA extends TestMonkey {
      method doMonkeyBusiness (line 30) | public void doMonkeyBusiness() {
    class MonkeyB (line 37) | private static class MonkeyB extends Monkey {
      type Type (line 38) | public enum Type implements MonkeyType {
      method type (line 42) | public Type type() {
      type Context (line 46) | public interface Context extends Monkey.Context {
        method getTrue (line 47) | boolean getTrue();
      method MonkeyB (line 52) | public MonkeyB(Context ctx) {
      method doMonkeyBusiness (line 57) | public void doMonkeyBusiness() {
    class MonkeyBContext (line 62) | private static class MonkeyBContext extends TestMonkeyContext implemen...
      method MonkeyBContext (line 63) | public MonkeyBContext() {
      method getTrue (line 67) | public boolean getTrue() {
    method testInstance (line 72) | @Test
    method testRunner (line 77) | @Test

FILE: src/test/java/com/netflix/simianarmy/TestUtils.java
  class TestUtils (line 29) | public final class TestUtils {
    method TestUtils (line 31) | private TestUtils() {
    method verifyTerminationTimeRough (line 54) | public static void verifyTerminationTimeRough(Resource resource, int r...

FILE: src/test/java/com/netflix/simianarmy/aws/TestAWSEmailNotifier.java
  class TestAWSEmailNotifier (line 24) | public class TestAWSEmailNotifier extends AWSEmailNotifier {
    method TestAWSEmailNotifier (line 25) | public TestAWSEmailNotifier() {
    method buildEmailSubject (line 29) | @Override
    method getCcAddresses (line 34) | @Override
    method getSourceAddress (line 39) | @Override
    method testEmailWithHashIsValid (line 44) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/TestRDSRecorder.java
  class TestRDSRecorder (line 45) | public class TestRDSRecorder extends RDSRecorder {
    method TestRDSRecorder (line 49) | public TestRDSRecorder() {
    type Type (line 53) | public enum Type implements MonkeyType {
    type EventTypes (line 57) | public enum EventTypes implements EventType {
    method testInit (line 61) | @Test
    method testInsertNewRecordEvent (line 70) | @SuppressWarnings("unchecked")
    method mkSelectResult (line 107) | private Event mkSelectResult(String id, Event evt) {
    method testFindEvent (line 113) | @SuppressWarnings("unchecked")
    method verifyEvents (line 144) | void verifyEvents(List<Event> events) {
    method testFindEventNotFound (line 164) | @SuppressWarnings("unchecked")

FILE: src/test/java/com/netflix/simianarmy/aws/TestSimpleDBRecorder.java
  class TestSimpleDBRecorder (line 51) | public class TestSimpleDBRecorder extends SimpleDBRecorder {
    method makeMockAWSClient (line 53) | private static AWSClient makeMockAWSClient() {
    method TestSimpleDBRecorder (line 61) | public TestSimpleDBRecorder() {
    method sdbClient (line 68) | @Override
    method superSdbClient (line 73) | protected AmazonSimpleDB superSdbClient() {
    method testClients (line 77) | @Test
    type Type (line 86) | public enum Type implements MonkeyType {
    type EventTypes (line 90) | public enum EventTypes implements EventType {
    method testRecordEvent (line 94) | @Test
    method mkSelectResult (line 128) | private SelectResult mkSelectResult(String id) {
    method testFindEvent (line 146) | @Test
    method verifyEvents (line 200) | void verifyEvents(List<Event> events) {

FILE: src/test/java/com/netflix/simianarmy/aws/conformity/TestASGOwnerEmailTag.java
  class TestASGOwnerEmailTag (line 40) | public class TestASGOwnerEmailTag {
    method testForOwnerTag (line 48) | @Test
    method createASGList (line 67) | private List<AutoScalingGroup> createASGList() {
    method makeASG (line 74) | private AutoScalingGroup makeASG(String asgName, String ownerEmail) {
    method createMockAWSClient (line 82) | private AWSClient createMockAWSClient(List<AutoScalingGroup> asgList, ...

FILE: src/test/java/com/netflix/simianarmy/aws/conformity/TestRDSConformityClusterTracker.java
  class TestRDSConformityClusterTracker (line 41) | public class TestRDSConformityClusterTracker extends RDSConformityCluste...
    method TestRDSConformityClusterTracker (line 42) | public TestRDSConformityClusterTracker() {
    method testInit (line 46) | @Test
    method testInsertNewCluster (line 55) | @SuppressWarnings("unchecked")
    method testUpdateCluster (line 96) | @SuppressWarnings("unchecked")
    method testGetCluster (line 137) | @SuppressWarnings("unchecked")
    method testGetClusters (line 156) | @SuppressWarnings("unchecked")
    method testGetClusterNotFound (line 178) | @SuppressWarnings("unchecked")

FILE: src/test/java/com/netflix/simianarmy/aws/conformity/rule/TestInstanceInVPC.java
  class TestInstanceInVPC (line 39) | public class TestInstanceInVPC {
    method setUp (line 47) | @BeforeMethod
    method testCheckSoloInstances (line 61) | @Test
    method testAsgInstances (line 74) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/TestAWSResource.java
  class TestAWSResource (line 35) | public class TestAWSResource {
    method testFieldToValueMapWithoutNullForInstance (line 38) | @Test
    method testFieldToValueMapWithNull (line 52) | @Test
    method testParseFieldToValueMap (line 60) | @Test
    method testClone (line 71) | @Test
    method verifyMapsAreEqual (line 80) | private void verifyMapsAreEqual(Map<String, String> map1, Map<String, ...
    method verifyTagsAreEqual (line 88) | private void verifyTagsAreEqual(Resource r1, Resource r2) {
    method getTestingFieldValueMap (line 98) | private Map<String, String> getTestingFieldValueMap(Date defaultDate, ...
    method getTestingResource (line 128) | private Resource getTestingResource(Date now) {
    method getTestingFields (line 148) | private Map<String, String> getTestingFields() {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/TestRDSJanitorResourceTracker.java
  class TestRDSJanitorResourceTracker (line 40) | public class TestRDSJanitorResourceTracker extends RDSJanitorResourceTra...
    method TestRDSJanitorResourceTracker (line 42) | public TestRDSJanitorResourceTracker() {
    method testInit (line 46) | @Test
    method testInsertNewResource (line 55) | @SuppressWarnings("unchecked")
    method testUpdateResource (line 123) | @SuppressWarnings("unchecked")
    method testGetResource (line 203) | @SuppressWarnings("unchecked")
    method testGetResourceNotFound (line 238) | @SuppressWarnings("unchecked")
    method testGetResources (line 250) | @SuppressWarnings("unchecked")
    method verifyResources (line 286) | private void verifyResources(List<Resource> resources, String id1, Str...
    method mkResource (line 332) | private AWSResource mkResource(String id, AWSResourceType resourceType...

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/TestSimpleDBJanitorResourceTracker.java
  class TestSimpleDBJanitorResourceTracker (line 53) | public class TestSimpleDBJanitorResourceTracker extends SimpleDBJanitorR...
    method makeMockAWSClient (line 55) | private static AWSClient makeMockAWSClient() {
    method TestSimpleDBJanitorResourceTracker (line 62) | public TestSimpleDBJanitorResourceTracker() {
    method testAddResource (line 69) | @Test
    method testGetResources (line 121) | @Test
    method verifyResources (line 156) | private void verifyResources(List<Resource> resources, String id1, Str...
    method mkSelectResult (line 195) | private SelectResult mkSelectResult(String id, AWSResourceType resourc...

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestASGJanitorCrawler.java
  class TestASGJanitorCrawler (line 39) | public class TestASGJanitorCrawler {
    method testResourceTypes (line 41) | @Test
    method testInstancesWithNullNames (line 49) | @Test
    method testInstancesWithNames (line 58) | @Test
    method testInstancesWithResourceType (line 68) | @Test
    method verifyASGList (line 83) | private void verifyASGList(List<Resource> resources, List<AutoScalingG...
    method verifyASG (line 91) | private void verifyASG(Resource asg, String asgName) {
    method createMockAWSClient (line 99) | private AWSClient createMockAWSClient(List<AutoScalingGroup> asgList, ...
    method createASGList (line 106) | private List<AutoScalingGroup> createASGList() {
    method mkASG (line 113) | private AutoScalingGroup mkASG(String asgName) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestEBSSnapshotJanitorCrawler.java
  class TestEBSSnapshotJanitorCrawler (line 39) | public class TestEBSSnapshotJanitorCrawler {
    method testResourceTypes (line 41) | @Test
    method testSnapshotsWithNullIds (line 51) | @Test
    method testSnapshotsWithIds (line 60) | @Test
    method testSnapshotsWithResourceType (line 70) | @Test
    method verifySnapshotList (line 85) | private void verifySnapshotList(List<Resource> resources, List<Snapsho...
    method verifySnapshot (line 93) | private void verifySnapshot(Resource snapshot, String snapshotId, Date...
    method createMockAWSClient (line 101) | private AWSClient createMockAWSClient(List<Snapshot> snapshotList, Str...
    method createSnapshotList (line 108) | private List<Snapshot> createSnapshotList(Date startTime) {
    method mkSnapshot (line 115) | private Snapshot mkSnapshot(String snapshotId, Date startTime) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestEBSVolumeJanitorCrawler.java
  class TestEBSVolumeJanitorCrawler (line 39) | public class TestEBSVolumeJanitorCrawler {
    method testResourceTypes (line 41) | @Test
    method testVolumesWithNullIds (line 51) | @Test
    method testVolumesWithIds (line 60) | @Test
    method testVolumesWithResourceType (line 70) | @Test
    method verifyVolumeList (line 85) | private void verifyVolumeList(List<Resource> resources, List<Volume> v...
    method verifyVolume (line 93) | private void verifyVolume(Resource volume, String volumeId, Date creat...
    method createMockAWSClient (line 101) | private AWSClient createMockAWSClient(List<Volume> volumeList, String....
    method createVolumeList (line 108) | private List<Volume> createVolumeList(Date createTime) {
    method mkVolume (line 115) | private Volume mkVolume(String volumeId, Date createTime) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestELBJanitorCrawler.java
  class TestELBJanitorCrawler (line 40) | public class TestELBJanitorCrawler {
    method testResourceTypes (line 42) | @Test
    method testElbsWithNoInstances (line 53) | @Test
    method testElbsWithInstances (line 64) | @Test
    method testElbsWithReferencedASGs (line 75) | @Test
    method testElbsWithNoReferencedASGs (line 89) | @Test
    method testElbsWithMultipleReferencedASGs (line 103) | @Test
    method verifyELBList (line 119) | private void verifyELBList(List<Resource> resources, List<LoadBalancer...
    method verifyELBList (line 123) | private void verifyELBList(List<Resource> resources, List<LoadBalancer...
    method verifyELB (line 131) | private void verifyELB(Resource asg, LoadBalancerDescription elb, int ...
    method createMockAWSClient (line 144) | private AWSClient createMockAWSClient() {
    method addELBsToMock (line 149) | private void addELBsToMock(AWSClient awsMock, List<LoadBalancerDescrip...
    method addASGsToMock (line 154) | private void addASGsToMock(AWSClient awsMock, List<AutoScalingGroup> a...
    method createELBList (line 159) | private List<LoadBalancerDescription> createELBList(boolean includeIns...
    method mkELB (line 166) | private LoadBalancerDescription mkELB(String elbName, boolean includeI...
    method createASGList (line 177) | private List<AutoScalingGroup> createASGList(boolean includeElbs) {
    method mkASG (line 189) | private AutoScalingGroup mkASG(String asgName, String elb) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestInstanceJanitorCrawler.java
  class TestInstanceJanitorCrawler (line 41) | public class TestInstanceJanitorCrawler {
    method testResourceTypes (line 43) | @Test
    method testInstancesWithNullIds (line 54) | @Test
    method testInstancesWithIds (line 64) | @Test
    method testInstancesWithResourceType (line 75) | @Test
    method testInstancesNotExistingInASG (line 91) | @Test
    method verifyInstanceList (line 101) | private void verifyInstanceList(List<Resource> resources, List<AutoSca...
    method verifyInstance (line 109) | private void verifyInstance(Resource instance, String instanceId, Stri...
    method createMockAWSClient (line 117) | private AWSClient createMockAWSClient(List<AutoScalingInstanceDetails>...
    method createInstanceDetailsList (line 126) | private List<AutoScalingInstanceDetails> createInstanceDetailsList() {
    method mkInstanceDetails (line 133) | private AutoScalingInstanceDetails mkInstanceDetails(String instanceId...
    method createInstanceList (line 137) | private List<Instance> createInstanceList() {
    method mkInstance (line 144) | private Instance mkInstance(String instanceId) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/crawler/TestLaunchConfigJanitorCrawler.java
  class TestLaunchConfigJanitorCrawler (line 38) | public class TestLaunchConfigJanitorCrawler {
    method testResourceTypes (line 40) | @Test
    method testInstancesWithNullNames (line 51) | @Test
    method testInstancesWithNames (line 61) | @Test
    method testInstancesWithResourceType (line 72) | @Test
    method verifyLaunchConfigList (line 88) | private void verifyLaunchConfigList(List<Resource> resources, List<Lau...
    method verifyLaunchConfig (line 100) | private void verifyLaunchConfig(Resource launchConfig, String lcName, ...
    method createMockAWSClient (line 110) | private AWSClient createMockAWSClient(List<AutoScalingGroup> asgList,
    method createLaunchConfigList (line 119) | private List<LaunchConfiguration> createLaunchConfigList(int n) {
    method mkLaunchConfig (line 127) | private LaunchConfiguration mkLaunchConfig(String lcName) {
    method createASGList (line 131) | private List<AutoScalingGroup> createASGList(int n) {
    method mkASG (line 140) | private AutoScalingGroup mkASG(String asgName, String lcName) {

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/TestMonkeyCalendar.java
  class TestMonkeyCalendar (line 35) | public class TestMonkeyCalendar implements MonkeyCalendar {
    method isMonkeyTime (line 36) | @Override
    method openHour (line 41) | @Override
    method closeHour (line 46) | @Override
    method now (line 51) | @Override
    method getBusinessDay (line 56) | @Override

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/asg/TestOldEmptyASGRule.java
  class TestOldEmptyASGRule (line 38) | public class TestOldEmptyASGRule {
    method testEmptyASGWithObsoleteLaunchConfig (line 39) | @Test
    method testEmptyASGWithValidLaunchConfig (line 56) | @Test
    method testASGWithInstances (line 73) | @Test
    method testASGWithoutInstanceAndNonZeroSize (line 91) | @Test
    method testEmptyASGWithoutLaunchConfig (line 108) | @Test
    method testEmptyASGWithLaunchConfigWithoutCreateTime (line 122) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 136) | @Test
    method testNullValidator (line 155) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullResource (line 160) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDays (line 166) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeLaunchConfigAgeThreshold (line 171) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullCalendar (line 176) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNonASGResource (line 181) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/asg/TestSuspendedASGRule.java
  class TestSuspendedASGRule (line 39) | public class TestSuspendedASGRule {
    method testEmptyASGSuspendedMoreThanThreshold (line 40) | @Test
    method testEmptyASGSuspendedLessThanThreshold (line 57) | @Test
    method testASGWithInstances (line 74) | @Test
    method testASGWithoutInstanceAndNonZeroSize (line 92) | @Test
    method testEmptyASGNotSuspended (line 109) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 122) | @Test
    method testNullResource (line 144) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullValidator (line 150) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDays (line 155) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeLaunchConfigAgeThreshold (line 160) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testSuspensionTimeIncorrectFormat (line 165) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNonASGResource (line 178) | @Test
    method testNullCalendar (line 186) | @Test(expectedExceptions = IllegalArgumentException.class)

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/elb/TestOrphanedELBRule.java
  class TestOrphanedELBRule (line 32) | public class TestOrphanedELBRule {
    method testELBWithNoInstancesNoASGs (line 34) | @Test
    method testELBWithInstancesNoASGs (line 46) | @Test
    method testELBWithReferencedASGsNoInstances (line 57) | @Test
    method testMissingInstanceCountCheck (line 68) | @Test
    method testMissingReferencedASGCountCheck (line 78) | @Test
    method testMissingCountsCheck (line 88) | @Test
    method testMissingCountsCheckWithExtraFields (line 97) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/generic/TestTagValueExclusionRule.java
  class TestTagValueExclusionRule (line 32) | public class TestTagValueExclusionRule {
    method beforeTest (line 36) | @BeforeTest
    method testExcludeTaggedResourceWithTagAndValueMatch1 (line 43) | @Test
    method testExcludeTaggedResourceWithTagAndValueMatch2 (line 54) | @Test
    method testExcludeTaggedResourceWithTagAndValueMatchBoth (line 65) | @Test
    method testExcludeTaggedResourceTagMatchOnly (line 76) | @Test
    method testExcludeTaggedResourceAllNullTags (line 87) | @Test
    method testExcludeTaggedResourceValueMatchOnly (line 98) | @Test
    method testExcludeUntaggedResource (line 109) | @Test
    method testNameValueConstructor (line 117) | @Test
    method testNameValueConstructor2 (line 128) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/generic/TestUntaggedRule.java
  class TestUntaggedRule (line 38) | public class TestUntaggedRule {
    method testUntaggedInstanceWithOwner (line 40) | @Test
    method testUntaggedInstanceWithoutOwner (line 57) | @Test
    method testTaggedInstance (line 73) | @Test
    method testUntaggedResource (line 88) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 111) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/instance/TestOrphanedInstanceRule.java
  class TestOrphanedInstanceRule (line 36) | public class TestOrphanedInstanceRule {
    method testOrphanedInstancesWithOwner (line 38) | @Test
    method testOrphanedInstancesWithoutOwner (line 54) | @Test
    method testOrphanedInstancesWithoutLaunchTime (line 69) | @Test
    method testOrphanedInstancesWithLaunchTimeNotExpires (line 82) | @Test
    method testNonOrphanedInstances (line 97) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 111) | @Test
    method testNullResource (line 131) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeAgeThreshold (line 137) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDaysWithOwner (line 142) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDaysWithoutOwner (line 147) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullCalendar (line 152) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNonInstanceResource (line 157) | @Test
    method testNonRunningInstance (line 166) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/launchconfig/TestOldUnusedLaunchConfigRule.java
  class TestOldUnusedLaunchConfigRule (line 37) | public class TestOldUnusedLaunchConfigRule {
    method testOldUnsedLaunchConfig (line 39) | @Test
    method testOldLaunchConfigWithNullFlag (line 53) | @Test
    method testUnsedLaunchConfigNotOld (line 66) | @Test
    method testUsedLaunchConfig (line 80) | @Test
    method testUsedLaunchConfigNoLaunchTimeSet (line 94) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 106) | @Test
    method testNullResource (line 125) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDays (line 131) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeLaunchConfigAgeThreshold (line 136) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullCalendar (line 141) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNonLaunchConfigResource (line 146) | @Test

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/snapshot/TestNoGeneratedAMIRule.java
  class TestNoGeneratedAMIRule (line 38) | public class TestNoGeneratedAMIRule {
    method testNonSnapshotResource (line 40) | @Test
    method testUncompletedVolume (line 49) | @Test
    method testTaggedAsNotMark (line 58) | @Test
    method testUserSpecifiedTerminationDate (line 73) | @Test
    method testOldSnapshotWithoutAMI (line 90) | @Test
    method testSnapshotWithoutAMINotOld (line 104) | @Test
    method testWithAMIs (line 118) | @Test
    method testSnapshotsWithoutLauchTime (line 133) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 146) | @Test
    method testOldSnapshotWithoutAMIWithOwnerOverride (line 165) | @Test
    method testOldSnapshotWithoutAMIWithoutOwnerOverride (line 180) | @Test
    method testNullResource (line 195) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeAgeThreshold (line 201) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDaysWithOwner (line 206) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullCalendar (line 211) | @Test(expectedExceptions = IllegalArgumentException.class)

FILE: src/test/java/com/netflix/simianarmy/aws/janitor/rule/volume/TestOldDetachedVolumeRule.java
  class TestOldDetachedVolumeRule (line 47) | public class TestOldDetachedVolumeRule {
    method testNonVolumeResource (line 49) | @Test
    method testUnavailableVolume (line 58) | @Test
    method testTaggedAsNotMark (line 67) | @Test
    method testNoMetaTag (line 85) | @Test
    method testUserSpecifiedTerminationDate (line 100) | @Test
    method testOldDetachedVolume (line 117) | @Test
    method testOldDetachedVolumeBeforeDaylightSavingsCutover (line 155) | @Test
    method testDetachedVolumeNotOld (line 199) | @Test
    method testAttachedVolume (line 216) | @Test
    method testResourceWithExpectedTerminationTimeSet (line 233) | @Test
    method testNullResource (line 255) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeAgeThreshold (line 261) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNgativeRetentionDaysWithOwner (line 266) | @Test(expectedExceptions = IllegalArgumentException.class)
    method testNullCalendar (line 271) | @Test(expectedExceptions = IllegalArgumentException.class)
    method verifyDSTCutoverHappened (line 283) | private void verifyDSTCutoverHappened(Resource resource, int retention...

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicCalendar.java
  class TestBasicCalendar (line 34) | public class TestBasicCalendar extends BasicCalendar {
    method TestBasicCalendar (line 38) | public TestBasicCalendar() {
    method testConstructors (line 42) | @Test
    method now (line 57) | @Override
    method setNow (line 62) | private void setNow(Calendar now) {
    method testMonkeyTime (line 66) | @Test
    method holidayDataProvider (line 105) | @DataProvider
    method testHolidays (line 120) | @Test(dataProvider = "holidayDataProvider")
    method testGetBusinessDayWihoutGap (line 132) | @Test
    method testGetBusinessDayWihWeekend (line 152) | @Test
    method testGetBusinessDayWihHoliday (line 172) | @Test
    method testGetBusinessDayWihHolidayNextYear (line 191) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicConfiguration.java
  class TestBasicConfiguration (line 26) | public class TestBasicConfiguration extends BasicConfiguration {
    method TestBasicConfiguration (line 29) | public TestBasicConfiguration() {
    method testGetBool (line 33) | @Test
    method testGetBoolOrElse (line 45) | @Test
    method testGetNumOrElse (line 60) | @Test
    method testGetStr (line 70) | @Test
    method testGetStrOrElse (line 79) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicContext.java
  class TestBasicContext (line 26) | public class TestBasicContext {
    method testContext (line 27) | @Test
    method testIsSafeToLogProperty (line 44) | @Test
    method testIsNotSafeToLogProperty (line 50) | @Test
    method testIsNotSafeToLogVsphereProperty (line 56) | @Test
    method testIsNotUsingProxyByDefault (line 62) | @Test
    method testIsAbleToUseProxyByConfiguration (line 74) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicMonkeyServer.java
  class TestBasicMonkeyServer (line 29) | @SuppressWarnings("serial")
    class SillyMonkey (line 35) | public static class SillyMonkey extends TestMonkey {
      method doMonkeyBusiness (line 36) | @Override
    method addMonkeysToRun (line 42) | @Override
    method testServer (line 48) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicRecorderEvent.java
  class TestBasicRecorderEvent (line 30) | public class TestBasicRecorderEvent {
    type Types (line 31) | public enum Types implements MonkeyType {
    type EventTypes (line 35) | public enum EventTypes implements EventType {
    method test (line 39) | @Test
    method testEvent (line 54) | void testEvent(BasicRecorderEvent evt) {

FILE: src/test/java/com/netflix/simianarmy/basic/TestBasicScheduler.java
  class TestBasicScheduler (line 40) | public class TestBasicScheduler {
    method testConstructors (line 42) | @Test
    type Enums (line 53) | private enum Enums implements MonkeyType {
    type EventEnums (line 57) | private enum EventEnums implements EventType {
    method testRunner (line 61) | @Test
    method testDelayedStart (line 84) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/calendar/TestBavarianCalendar.java
  class TestBavarianCalendar (line 32) | public class TestBavarianCalendar extends BavarianCalendar {
    method TestBavarianCalendar (line 36) | public TestBavarianCalendar() {
    method now (line 42) | @Override
    method setNow (line 47) | private void setNow(Calendar now) {
    method easterDataProvider (line 51) | @DataProvider
    method testEaster (line 98) | @Test(dataProvider = "easterDataProvider")
    method holidayDataProvider (line 103) | @DataProvider
    method testHolidays (line 141) | @Test(dataProvider = "holidayDataProvider")

FILE: src/test/java/com/netflix/simianarmy/basic/chaos/TestBasicChaosEmailNotifier.java
  class TestBasicChaosEmailNotifier (line 36) | public class TestBasicChaosEmailNotifier {
    type GroupTypes (line 44) | private enum GroupTypes implements GroupType {
    method beforeMethod (line 65) | @BeforeMethod
    method testInvalidEmailAddresses (line 70) | @Test
    method testValidEmailAddresses (line 86) | @Test
    method testbuildEmailSubject (line 105) | @Test
    method testbuildEmailSubjectWithSubjectPrefix (line 112) | @Test
    method testbuildEmailSubjectWithSubjectSuffix (line 120) | @Test
    method testbuildEmailSubjectWithSubjectPrefixSuffix (line 128) | @Test
    method testbuildEmailBody (line 137) | @Test
    method testbuildEmailBodyPrefix (line 144) | @Test
    method testbuildEmailBodySuffix (line 152) | @Test
    method testbuildEmailBodyPrefixSuffix (line 160) | @Test
    method testBuildAndSendEmail (line 169) | @Test
    method testBuildAndSendEmailSubjectIsBody (line 179) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/chaos/TestBasicChaosInstanceSelector.java
  class TestBasicChaosInstanceSelector (line 36) | public class TestBasicChaosInstanceSelector {
    method logger (line 39) | protected Logger logger() {
    type Types (line 44) | public enum Types implements GroupType {
    method type (line 49) | public GroupType type() {
    method name (line 53) | public String name() {
    method region (line 57) | public String region() {
    method tags (line 61) | public List<TagDescription> tags() {
    method instances (line 65) | public List<String> instances() {
    method addInstance (line 70) | public void addInstance(String ignored) {
    method copyAs (line 73) | @Override
    method testSelect (line 79) | @Test
    method evenSelectionDataProvider (line 93) | @DataProvider
    method testEvenSelections (line 101) | @Test(dataProvider = "evenSelectionDataProvider")
    method testSelectWithProbMoreThanOne (line 129) | @Test
    method testSelectWithProbMoreThanOneWithFraction (line 142) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/chaos/TestBasicChaosMonkey.java
  class TestBasicChaosMonkey (line 41) | public class TestBasicChaosMonkey {
    type GroupTypes (line 42) | private enum GroupTypes implements GroupType {
    method testDisabled (line 46) | @Test
    method testEnabledA (line 58) | @Test
    method testUnleashedEnabledA (line 74) | @Test
    method testEnabledB (line 92) | @Test
    method testUnleashedEnabledB (line 108) | @Test
    method testEnabledAwithout1 (line 126) | @Test
    method testEnabledAwith0 (line 141) | @Test
    method testAll (line 156) | @Test
    method testNoProbability (line 180) | @Test
    method testFullProbability (line 200) | @Test
    method testNoProbabilityByName (line 248) | @Test
    method testMaxTerminationCountPerDayAsZero (line 268) | @Test
    method testMaxTerminationCountPerDayAsOne (line 278) | @Test
    method testMaxTerminationCountPerDayAsBiggerThanOne (line 294) | @Test
    method testMaxTerminationCountPerDayAsSmallerThanOne (line 310) | @Test
    method testMaxTerminationCountPerDayAsNegative (line 326) | @Test
    method testMaxTerminationCountPerDayAsVerySmall (line 336) | @Test
    method testMaxTerminationCountPerDayGroupLevel (line 346) | @Test
    method testGetValueFromCfgWithDefault (line 364) | @Test
    method testMandatoryTerminationDisabled (line 392) | @Test
    method testMandatoryTerminationNotDefined (line 402) | @Test
    method testMandatoryTerminationNoOptInTime (line 412) | @Test
    method testMandatoryTerminationInsideWindow (line 422) | @Test
    method testMandatoryTerminationOutsideWindow (line 433) | @Test
    method testMandatoryTerminationOutsideWindowWithPreviousTermination (line 444) | @Test
    method testMandatoryTerminationInsideWindowWithPreviousTermination (line 458) | @Test
    method testNotificationEnabled (line 472) | @Test
    method testGlobalNotificationEnabled (line 484) | @Test
    method terminateOnDemand (line 496) | private void terminateOnDemand(TestChaosMonkeyContext ctx, String grou...
    method validateAddEventResult (line 509) | private void validateAddEventResult(ChaosMonkeyResource resource, Stri...

FILE: src/test/java/com/netflix/simianarmy/basic/chaos/TestCloudFormationChaosMonkey.java
  class TestCloudFormationChaosMonkey (line 33) | public class TestCloudFormationChaosMonkey {
    method testIsGroupEnabled (line 37) | @Test
    method testIsMaxTerminationCountExceeded (line 49) | @Test
    method testGetEffectiveProbability (line 58) | @Test
    method testNoSuffixInstanceGroup (line 67) | @Test
    method testGetLastOptInMilliseconds (line 77) | @Test
    method testCloudFormationChaosMonkeyIntegration (line 86) | @Test

FILE: src/test/java/com/netflix/simianarmy/basic/janitor/TestBasicJanitorRuleEngine.java
  class TestBasicJanitorRuleEngine (line 31) | public class TestBasicJanitorRuleEngine {
    method testEmptyRuleSet (line 33) | @Test
    method testAllValid (line 40) | @Test
    method testMixed (line 50) | @Test
    method testIsValidWithNearestTerminationTime (line 61) | @Test
    method testWithExclusionRuleMatch1 (line 80) | @Test void testWithExclusionRuleMatch1() {
    method testWithExclusionRuleMatch2 (line 89) | @Test void testWithExclusionRuleMatch2() {
    method testWithExclusionRuleNotMatch1 (line 98) | @Test void testWithExclusionRuleNotMatch1() {
    method testWithExclusionRuleNotMatch2 (line 107) | @Test void testWithExclusionRuleNotMatch2() {
  class AlwaysValidRule (line 117) | class AlwaysValidRule implements Rule {
    method isValid (line 118) | @Override
  class AlwaysInvalidRule (line 124) | class AlwaysInvalidRule implements Rule {
    method AlwaysInvalidRule (line 128) | public AlwaysInvalidRule(DateTime now, int retentionDays) {
    method isValid (line 133) | @Override

FILE: src/test/java/com/netflix/simianarmy/chaos/TestChaosMonkeyArmy.java
  class TestChaosMonkeyArmy (line 38) | public class TestChaosMonkeyArmy {
    method createSshKey (line 41) | @BeforeTest
    method runChaosMonkey (line 48) | private TestChaosMonkeyContext runChaosMonkey(String key) {
    method runChaosMonkey (line 52) | private TestChaosMonkeyContext runChaosMonkey(String key, boolean burn...
    method checkSelected (line 74) | private void checkSelected(TestChaosMonkeyContext ctx) {
    method checkNotifications (line 83) | private void checkNotifications(TestChaosMonkeyContext ctx, String key) {
    method checkSshActions (line 92) | private void checkSshActions(TestChaosMonkeyContext ctx, String key) {
    method testShutdownInstance (line 114) | @Test
    method testBlockAllNetworkTraffic (line 130) | @Test
    method testDetachVolumes (line 147) | @Test
    method testBurnCpu (line 165) | @Test
    method testBurnIo (line 176) | @Test
    method testBurnIoWithoutBurnMoney (line 187) | @Test
    method testFillDisk (line 202) | @Test
    method testFillDiskWithoutBurnMoney (line 213) | @Test
    method testFailDns (line 229) | @Test
    method testFailDynamoDb (line 240) | @Test
    method testFailEc2 (line 251) | @Test
    method testFailS3 (line 262) | @Test
    method testKillProcess (line 273) | @Test
    method testNetworkCorruption (line 284) | @Test
    method testNetworkLatency (line 295) | @Test
    method testNetworkLoss (line 306) | @Test
    method testNullRoute (line 317) | @Test

FILE: src/test/java/com/netflix/simianarmy/chaos/TestChaosMonkeyContext.java
  class TestChaosMonkeyContext (line 44) | public class TestChaosMonkeyContext extends TestMonkeyContext implements...
    method TestChaosMonkeyContext (line 48) | public TestChaosMonkeyContext() {
    method TestChaosMonkeyContext (line 52) | protected TestChaosMonkeyContext(Properties properties) {
    method TestChaosMonkeyContext (line 57) | public TestChaosMonkeyContext(String propFile) {
    method configuration (line 73) | @Override
    class TestInstanceGroup (line 78) | public static class TestInstanceGroup implements InstanceGroup {
      method TestInstanceGroup (line 85) | public TestInstanceGroup(GroupType type, String name, String region,...
      method tags (line 94) | @Override
      method type (line 99) | @Override
      method name (line 104) | @Override
      method region (line 109) | @Override
      method instances (line 114) | @Override
      method addInstance (line 119) | @Override
      method deleteInstance (line 123) | public void deleteInstance(String id) {
      method copyAs (line 127) | @Override
    type CrawlerTypes (line 133) | public enum CrawlerTypes implements GroupType {
    method chaosCrawler (line 137) | @Override
    method selectedOn (line 186) | public List<InstanceGroup> selectedOn() {
    method chaosInstanceSelector (line 190) | @Override
    method terminated (line 207) | public List<String> terminated() {
    method cloudClient (line 213) | @Override
    class SshAction (line 311) | public static class SshAction {
      method getInstanceId (line 318) | public String getInstanceId() {
      method getMethod (line 322) | public String getMethod() {
      method getPath (line 326) | public String getPath() {
      method getContents (line 330) | public String getContents() {
      method getCommand (line 334) | public String getCommand() {
    class MockSshClient (line 339) | private class MockSshClient implements SshClient {
      method MockSshClient (line 343) | public MockSshClient(String instanceId, LoginCredentials credentials) {
      method getUsername (line 348) | @Override
      method getHostAddress (line 353) | @Override
      method put (line 358) | @Override
      method get (line 363) | @Override
      method exec (line 368) | @Override
      method execChannel (line 382) | @Override
      method connect (line 387) | @Override
      method disconnect (line 391) | @Override
      method put (line 395) | @Override
    class Notification (line 409) | static class Notification {
      method Notification (line 413) | public Notification(String instance, ChaosType chaosType) {
      method getInstance (line 418) | public String getInstance() {
      method getChaosType (line 422) | public ChaosType getChaosType() {
    method chaosEmailNotifier (line 427) | @Override
    method getNotified (line 457) | public int getNotified() {
    method getGloballyNotified (line 461) | public int getGloballyNotified() {
    method getNotifiedList (line 465) | public List<Notification> getNotifiedList() {
    method getGloballyNotifiedList (line 469) | public List<Notification> getGloballyNotifiedList() {
    method getSshActions (line 473) | public List<SshAction> getSshActions() {
    method getCloudActions (line 477) | public List<String> getCloudActions() {

FILE: src/test/java/com/netflix/simianarmy/client/aws/TestAWSClient.java
  class TestAWSClient (line 41) | public class TestAWSClient extends AWSClient {
    method TestAWSClient (line 42) | public TestAWSClient() {
    method ec2Client (line 48) | protected AmazonEC2 ec2Client() {
    method asgClient (line 54) | protected AmazonAutoScalingClient asgClient() {
    method superEc2Client (line 58) | protected AmazonEC2 superEc2Client() {
    method superAsgClient (line 62) | protected AmazonAutoScalingClient superAsgClient() {
    method testClients (line 66) | @Test
    method testTerminateInstance (line 73) | @Test
    method mkAsgResult (line 87) | private DescribeAutoScalingGroupsResult mkAsgResult(String asgName, St...
    method testDescribeAutoScalingGroups (line 98) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/aws/chaos/TestASGChaosCrawler.java
  class TestASGChaosCrawler (line 44) | public class TestASGChaosCrawler {
    method mkAsg (line 47) | private AutoScalingGroup mkAsg(String asgName, String instanceId) {
    method TestASGChaosCrawler (line 58) | public TestASGChaosCrawler() {
    method testGroupTypes (line 63) | @Test
    method testGroups (line 70) | @Test
    method testFindAggressionCoefficient (line 95) | @Test
    method testFindAggressionCoefficient_two (line 107) | @Test
    method testFindAggressionCoefficient_null (line 119) | @Test
    method testFindAggressionCoefficient_unparsable (line 131) | @Test
    method makeTunableTag (line 143) | private TagDescription makeTunableTag(String value) {
    method testGetInstanceGroup_basic (line 150) | @Test
    method testGetInstanceGroup_tunable (line 160) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/aws/chaos/TestFilterASGChaosCrawler.java
  class TestFilterASGChaosCrawler (line 37) | public class TestFilterASGChaosCrawler {
    type Types (line 43) | public enum Types implements GroupType {
    method beforeTest (line 49) | @BeforeTest
    method testFilterGroups (line 57) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/vsphere/TestPropertyBasedTerminationStrategy.java
  class TestPropertyBasedTerminationStrategy (line 36) | public class TestPropertyBasedTerminationStrategy {
    method shouldReturnConfiguredPropertyNameAndValueAfterConstructedFromConfig (line 40) | @Test
    method shouldSetPropertyAndResetVirtualMachineAfterTermination (line 53) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/vsphere/TestVSpehereClient.java
  class TestVSpehereClient (line 38) | public class TestVSpehereClient {
    method shouldTerminateCorrectly (line 39) | @Test
    method shouldDescribeGroupsCorrectly (line 53) | @Test
    method flattenGroups (line 70) | private String flattenGroups(List<AutoScalingGroup> groups) {
    method createVMMock (line 82) | private VirtualMachine createVMMock(String id) {

FILE: src/test/java/com/netflix/simianarmy/client/vsphere/TestVSphereContext.java
  class TestVSphereContext (line 29) | public class TestVSphereContext {
    method shouldSetClientOfCorrectType (line 30) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/vsphere/TestVSphereGroups.java
  class TestVSphereGroups (line 30) | public class TestVSphereGroups {
    method shouldReturnListContainigSingleASGWhenAddInstanceIsCalledOnce (line 31) | @Test
    method shouldReturnListContainingSingleASGWithTwoInstancesWhenAddInstanceIsCaledTwiceForSameGroup (line 48) | @Test
    method shouldReturnListContainigTwoASGWhenAddInstanceIsCalledTwice (line 64) | @Test

FILE: src/test/java/com/netflix/simianarmy/client/vsphere/TestVSphereServiceConnection.java
  class TestVSphereServiceConnection (line 42) | public class TestVSphereServiceConnection {
    method shouldReturnConfiguredPropertiesAfterConstructedFromConfig (line 46) | @Test
    method shouldCallSearchManagedEntityAndReturnVMForDoItGetVirtualMachineById (line 59) | @Test
    method shouldThrowExceptionWhenCallingSearchManagedEntitiesOnDescribeWhenNoVMsAreReturned (line 75) | @Test //(expectedExceptions = AmazonServiceException.class)
    method shouldCallSearchManagedEntitiesOnDescribeWhenAtLeastOneVMIsReturned (line 88) | @Test
    method shouldEncapsulateInvalidPropertyException (line 104) | @Test(expectedExceptions = AmazonServiceException.class)
    method shouldEncapsulateRuntimeFaultException (line 114) | @Test(expectedExceptions = AmazonServiceException.class)
    method shouldEncapsulateRemoteExceptionException (line 124) | @Test(expectedExceptions = AmazonServiceException.class)
  class VSphereServiceConnectionWithMockedInventoryNavigator (line 163) | class VSphereServiceConnectionWithMockedInventoryNavigator extends VSphe...
    method VSphereServiceConnectionWithMockedInventoryNavigator (line 166) | public VSphereServiceConnectionWithMockedInventoryNavigator() {
    method getInventoryNavigator (line 170) | @Override
    method getInventoryNavigatorMock (line 175) | public InventoryNavigator getInventoryNavigatorMock() {

FILE: src/test/java/com/netflix/simianarmy/conformity/TestCrossZoneLoadBalancing.java
  class TestCrossZoneLoadBalancing (line 34) | public class TestCrossZoneLoadBalancing extends CrossZoneLoadBalancing {
    method init (line 38) | @BeforeClass
    method testDisabledCrossZoneLoadBalancing (line 46) | @Test
    method testEnabledCrossZoneLoadBalancing (line 55) | @Test
    method testAsgWithoutElb (line 63) | @Test
    method getLoadBalancerNamesForAsg (line 71) | @Override
    method isCrossZoneLoadBalancingEnabled (line 76) | @Override

FILE: src/test/java/com/netflix/simianarmy/conformity/TestSameZonesInElbAndAsg.java
  class TestSameZonesInElbAndAsg (line 32) | public class TestSameZonesInElbAndAsg extends SameZonesInElbAndAsg {
    method init (line 37) | @BeforeClass
    method testZoneMismatch (line 49) | @Test
    method testZoneMatch (line 58) | @Test
    method testAsgWithoutElb (line 66) | @Test
    method getLoadBalancerNamesForAsg (line 74) | @Override
    method getAvailabilityZonesForAsg (line 79) | @Override
    method getAvailabilityZonesForLoadBalancer (line 84) | @Override

FILE: src/test/java/com/netflix/simianarmy/janitor/TestAbstractJanitor.java
  class TestAbstractJanitor (line 36) | public class TestAbstractJanitor extends AbstractJanitor {
    method TestAbstractJanitor (line 40) | public TestAbstractJanitor(AbstractJanitor.Context ctx, ResourceType r...
    method postMark (line 54) | @Override
    method cleanup (line 59) | @Override
    method cleanupDryRun (line 71) | @Override
    method postCleanup (line 87) | @Override
    method generateTestingResources (line 92) | private static List<Resource> generateTestingResources(int n) {
    method testJanitor (line 103) | @Test
    method testJanitorWithOptedOutResources (line 146) | @Test
    method testJanitorWithCleanupFailure (line 209) | @Test
    method getJanitor (line 238) | private static TestAbstractJanitor getJanitor(int numberOfCrawledResou...
    method testCleanupDryRunOnWithJanitorOnLeashWithAFailure (line 248) | @Test
    method testJanitorWithUnmarking (line 264) | @Test
    method testJanitorWithFutureTerminationTime (line 317) | @Test
    method testJanitorWithoutNotification (line 359) | @Test
    method testLeashedJanitorForMarking (line 397) | @Test
    method testJanitorWithoutHoldingOffCleanup (line 424) | @Test
    method testJanitorWithUnmarkingUserTerminated (line 467) | public static void testJanitorWithUnmarkingUserTerminated() {
  class TestJanitorCrawler (line 517) | class TestJanitorCrawler implements JanitorCrawler {
    method getCrawledResources (line 519) | public Collection<Resource> getCrawledResources() {
    method TestJanitorCrawler (line 523) | public TestJanitorCrawler(Collection<Resource> crawledResources) {
    method resourceTypes (line 527) | @Override
    method resources (line 532) | @Override
    method resources (line 537) | @Override
    method getOwnerEmailForResource (line 549) | @Override
  type TestResourceType (line 555) | enum TestResourceType implements ResourceType {
  class TestJanitorResourceTracker (line 559) | class TestJanitorResourceTracker implements JanitorResourceTracker {
    method TestJanitorResourceTracker (line 561) | public TestJanitorResourceTracker(Map<String, Resource> trackedResourc...
    method addOrUpdate (line 565) | @Override
    method getResources (line 570) | @Override
    method getResource (line 583) | @Override
    method getResource (line 588) | @Override
  class IsEvenRule (line 598) | class IsEvenRule implements Rule {
    method isValid (line 599) | @Override
  class ImmediateCleanupRule (line 621) | class ImmediateCleanupRule implements Rule {
    method ImmediateCleanupRule (line 623) | public ImmediateCleanupRule(DateTime now) {
    method isValid (line 626) | @Override
  class TestJanitorContext (line 634) | class TestJanitorContext implements AbstractJanitor.Context {
    method TestJanitorContext (line 641) | public TestJanitorContext(String region, JanitorRuleEngine ruleEngine,...
    method region (line 650) | @Override
    method calendar (line 655) | @Override
    method janitorRuleEngine (line 660) | @Override
    method janitorCrawler (line 665) | @Override
    method janitorResourceTracker (line 670) | @Override
    method configuration (line 675) | @Override
    method recorder (line 680) | @Override

FILE: src/test/java/com/netflix/simianarmy/janitor/TestBasicJanitorMonkeyContext.java
  class TestBasicJanitorMonkeyContext (line 35) | public class TestBasicJanitorMonkeyContext {
    method TestBasicJanitorMonkeyContext (line 51) | public TestBasicJanitorMonkeyContext() {
    method before (line 55) | @BeforeMethod
    method testAddRuleWithUntaggedRuleResource (line 61) | @Test
    method testAddRuleWithoutUntaggedRuleResource (line 75) | @Test
    method getUntaggedRuleResourceSet (line 89) | private Set<String> getUntaggedRuleResourceSet() {

FILE: src/test/java/com/netflix/simianarmy/resources/chaos/TestChaosMonkeyResource.java
  class TestChaosMonkeyResource (line 56) | public class TestChaosMonkeyResource {
    method init (line 73) | @BeforeTest
    method testTerminateNow (line 78) | @Test
    method testTerminateNowDisabled (line 109) | @Test
    method testTerminateNowBadInput (line 123) | @Test
    method testTerminateNowBadGroupNotExist (line 140) | @Test
    method testTerminateNowBadEventType (line 153) | @Test
    method testResource (line 162) | @Test
    method mkEvent (line 201) | private MonkeyRecorder.Event mkEvent(String instance) {
    class MockTestChaosMonkeyContext (line 209) | public static class MockTestChaosMonkeyContext extends TestChaosMonkey...
      method recorder (line 210) | @Override
    method getResource (line 216) | String getResource(String name) {
    method validateAddEventResult (line 221) | private void validateAddEventResult(ChaosMonkeyResource resource, Stri...

FILE: src/test/java/com/netflix/simianarmy/tunable/TestTunablyAggressiveChaosMonkey.java
  class TestTunablyAggressiveChaosMonkey (line 31) | public class TestTunablyAggressiveChaosMonkey {
    type GroupTypes (line 32) | private enum GroupTypes implements GroupType {
    method testFullProbability_basic (line 36) | @Test
    method testFullProbability_tuned (line 49) | @Test
Condensed preview — 289 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,399K chars).
[
  {
    "path": ".gitignore",
    "chars": 815,
    "preview": "# Compiled source #\n###################\n*.com\n*.class\n*.dll\n*.exe\n*.o\n*.so\n\n# Packages #\n############\n# it's better to u"
  },
  {
    "path": ".netflixoss",
    "chars": 24,
    "preview": "cloudbees_disabled=true\n"
  },
  {
    "path": ".travis.yml",
    "chars": 922,
    "preview": "language: java\njdk:\n- oraclejdk8\nsudo: required\ndist: trusty\ninstall: ./installViaTravis.sh\nscript: ./buildViaTravis.sh\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "GNUmakefile",
    "chars": 290,
    "preview": "reformat:\n\teclipse -nosplash -application org.eclipse.jdt.core.JavaCodeFormatter -verbose -config $(shell pwd)/codequali"
  },
  {
    "path": "LICENSE",
    "chars": 11344,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "OSSMETADATA",
    "chars": 22,
    "preview": "osslifecycle=archived\n"
  },
  {
    "path": "README.md",
    "chars": 2002,
    "preview": "[![NetflixOSS Lifecycle](https://img.shields.io/osslifecycle/Netflix/SimianArmy.svg)](OSSMETADATA)\n[![Build Status](http"
  },
  {
    "path": "build.gradle",
    "chars": 2262,
    "preview": "buildscript {\n    repositories {\n        jcenter()\n    }\n}\n\nplugins {\n    id 'nebula.netflixoss' version '3.2.3'\n    id "
  },
  {
    "path": "buildViaTravis.sh",
    "chars": 1344,
    "preview": "#!/bin/bash\n# This script will build the project.\n\nif [ \"$TRAVIS_PULL_REQUEST\" != \"false\" ]; then\n  echo -e \"Build Pull "
  },
  {
    "path": "codequality/checkstyle.xml",
    "chars": 7669,
    "preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\"\n    \"http://www.pupp"
  },
  {
    "path": "codequality/org.eclipse.jdt.core.prefs",
    "chars": 23862,
    "preview": "eclipse.preferences.version=1\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\norg.eclipse.jdt.core.compi"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Feb 22 15:12:15 PST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "installViaTravis.sh",
    "chars": 806,
    "preview": "#!/bin/bash\n# This script will build the project.\n\nif [ \"$TRAVIS_PULL_REQUEST\" != \"false\" ]; then\n  echo -e \"Assemble Pu"
  },
  {
    "path": "settings.gradle",
    "chars": 30,
    "preview": "rootProject.name='simianarmy'\n"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/AbstractEmailBuilder.java",
    "chars": 2746,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/CloudClient.java",
    "chars": 6586,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/EmailBuilder.java",
    "chars": 963,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/EventType.java",
    "chars": 784,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/FeatureNotEnabledException.java",
    "chars": 1142,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/GroupType.java",
    "chars": 784,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/InstanceGroupNotFoundException.java",
    "chars": 1748,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/Monkey.java",
    "chars": 4104,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyCalendar.java",
    "chars": 1895,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyConfiguration.java",
    "chars": 2595,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyEmailNotifier.java",
    "chars": 1748,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyRecorder.java",
    "chars": 4565,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyRunner.java",
    "chars": 8516,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyScheduler.java",
    "chars": 1764,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/MonkeyType.java",
    "chars": 786,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/NamedType.java",
    "chars": 819,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/NotFoundException.java",
    "chars": 1893,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/Resource.java",
    "chars": 11589,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/ResourceType.java",
    "chars": 790,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/AWSEmailNotifier.java",
    "chars": 4078,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/AWSResource.java",
    "chars": 18329,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/AWSResourceType.java",
    "chars": 1242,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/RDSRecorder.java",
    "chars": 9320,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/STSAssumeRoleSessionCredentialsProvider.java",
    "chars": 9080,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/SimpleDBRecorder.java",
    "chars": 11108,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/RDSConformityClusterTracker.java",
    "chars": 13658,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/SimpleDBConformityClusterTracker.java",
    "chars": 8622,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/crawler/AWSClusterCrawler.java",
    "chars": 8218,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/BasicConformityEurekaClient.java",
    "chars": 3306,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/ConformityEurekaClient.java",
    "chars": 1774,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/CrossZoneLoadBalancing.java",
    "chars": 5297,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceHasHealthCheckUrl.java",
    "chars": 2885,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceHasStatusUrl.java",
    "chars": 2826,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceInSecurityGroup.java",
    "chars": 6985,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceInVPC.java",
    "chars": 4666,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceIsHealthyInEureka.java",
    "chars": 2941,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/InstanceTooOld.java",
    "chars": 5370,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/conformity/rule/SameZonesInElbAndAsg.java",
    "chars": 6676,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/ASGJanitor.java",
    "chars": 1895,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/EBSSnapshotJanitor.java",
    "chars": 1933,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/EBSVolumeJanitor.java",
    "chars": 1919,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/ELBJanitor.java",
    "chars": 3807,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/ImageJanitor.java",
    "chars": 1906,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/InstanceJanitor.java",
    "chars": 1931,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/LaunchConfigJanitor.java",
    "chars": 1964,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/RDSJanitorResourceTracker.java",
    "chars": 16376,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/SimpleDBJanitorResourceTracker.java",
    "chars": 8256,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/VolumeTaggingMonkey.java",
    "chars": 13435,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/ASGJanitorCrawler.java",
    "chars": 7710,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/AbstractAWSJanitorCrawler.java",
    "chars": 1973,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/EBSSnapshotJanitorCrawler.java",
    "chars": 5956,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/EBSVolumeJanitorCrawler.java",
    "chars": 4416,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/ELBJanitorCrawler.java",
    "chars": 6526,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/InstanceJanitorCrawler.java",
    "chars": 5754,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/LaunchConfigJanitorCrawler.java",
    "chars": 3664,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaASGJanitorCrawler.java",
    "chars": 13576,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaEBSSnapshotJanitorCrawler.java",
    "chars": 9865,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaEBSVolumeJanitorCrawler.java",
    "chars": 16004,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaELBJanitorCrawler.java",
    "chars": 16875,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaImageJanitorCrawler.java",
    "chars": 23864,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaInstanceJanitorCrawler.java",
    "chars": 12583,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaLaunchConfigJanitorCrawler.java",
    "chars": 6765,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/crawler/edda/EddaUtils.java",
    "chars": 2618,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/ami/UnusedImageRule.java",
    "chars": 5339,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/ASGInstanceValidator.java",
    "chars": 1112,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/DiscoveryASGInstanceValidator.java",
    "chars": 4393,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/DummyASGInstanceValidator.java",
    "chars": 2280,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/OldEmptyASGRule.java",
    "chars": 7356,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/asg/SuspendedASGRule.java",
    "chars": 4582,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/elb/OrphanedELBRule.java",
    "chars": 3989,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/generic/TagValueExclusionRule.java",
    "chars": 2905,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/generic/UntaggedRule.java",
    "chars": 3678,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/instance/OrphanedInstanceRule.java",
    "chars": 6405,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/launchconfig/OldUnusedLaunchConfigRule.java",
    "chars": 4280,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/snapshot/NoGeneratedAMIRule.java",
    "chars": 7095,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/volume/DeleteOnTerminationRule.java",
    "chars": 5085,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/aws/janitor/rule/volume/OldDetachedVolumeRule.java",
    "chars": 6012,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicCalendar.java",
    "chars": 9411,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicChaosMonkeyContext.java",
    "chars": 4231,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicConfiguration.java",
    "chars": 2886,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicMonkeyServer.java",
    "chars": 6007,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicRecorderEvent.java",
    "chars": 3749,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicScheduler.java",
    "chars": 4168,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/BasicSimianArmyContext.java",
    "chars": 16485,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/LocalDbRecorder.java",
    "chars": 10581,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/calendars/BavarianCalendar.java",
    "chars": 5660,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosEmailNotifier.java",
    "chars": 7079,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosInstanceSelector.java",
    "chars": 3335,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/chaos/BasicChaosMonkey.java",
    "chars": 19531,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/chaos/BasicInstanceGroup.java",
    "chars": 2743,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/chaos/CloudFormationChaosMonkey.java",
    "chars": 3141,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityEmailBuilder.java",
    "chars": 5195,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityMonkey.java",
    "chars": 9788,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/conformity/BasicConformityMonkeyContext.java",
    "chars": 11354,
    "preview": "/*\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorEmailBuilder.java",
    "chars": 5298,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorMonkey.java",
    "chars": 11035,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorMonkeyContext.java",
    "chars": 28517,
    "preview": "/*\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorRuleEngine.java",
    "chars": 4999,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/basic/janitor/BasicVolumeTaggingMonkeyContext.java",
    "chars": 1674,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/BlockAllNetworkTrafficChaosType.java",
    "chars": 3412,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/BurnCpuChaosType.java",
    "chars": 1181,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/BurnIoChaosType.java",
    "chars": 2583,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosCrawler.java",
    "chars": 2537,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosEmailNotifier.java",
    "chars": 2094,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosInstance.java",
    "chars": 3617,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosInstanceSelector.java",
    "chars": 2591,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosMonkey.java",
    "chars": 4723,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ChaosType.java",
    "chars": 4307,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/DetachVolumesChaosType.java",
    "chars": 2625,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/FailDnsChaosType.java",
    "chars": 1062,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/FailDynamoDbChaosType.java",
    "chars": 1099,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/FailEc2ChaosType.java",
    "chars": 1079,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/FailS3ChaosType.java",
    "chars": 1075,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/FillDiskChaosType.java",
    "chars": 1908,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/KillProcessesChaosType.java",
    "chars": 1116,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/NetworkCorruptionChaosType.java",
    "chars": 1099,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/NetworkLatencyChaosType.java",
    "chars": 1080,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/NetworkLossChaosType.java",
    "chars": 1075,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/NullRouteChaosType.java",
    "chars": 1276,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ScriptChaosType.java",
    "chars": 2974,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/ShutdownInstanceChaosType.java",
    "chars": 1613,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/chaos/SshConfig.java",
    "chars": 3115,
    "preview": "/*\n *\n *  Copyright 2013 Justin Santa Barbara.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/MonkeyRestClient.java",
    "chars": 4120,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/aws/AWSClient.java",
    "chars": 38651,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/aws/chaos/ASGChaosCrawler.java",
    "chars": 5475,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/aws/chaos/FilteringChaosCrawler.java",
    "chars": 2296,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/aws/chaos/TagPredicate.java",
    "chars": 1656,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/edda/EddaClient.java",
    "chars": 2005,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/PropertyBasedTerminationStrategy.java",
    "chars": 2377,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/TerminationStrategy.java",
    "chars": 1103,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/VSphereClient.java",
    "chars": 3513,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/VSphereContext.java",
    "chars": 1459,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/VSphereGroups.java",
    "chars": 2319,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/client/vsphere/VSphereServiceConnection.java",
    "chars": 5321,
    "preview": "/*\r\n *  Copyright 2012 Immobilien Scout GmbH\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *"
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/AutoScalingGroup.java",
    "chars": 2392,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/Cluster.java",
    "chars": 10990,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ClusterCrawler.java",
    "chars": 1574,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/Conformity.java",
    "chars": 2092,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityClusterTracker.java",
    "chars": 2315,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityEmailBuilder.java",
    "chars": 1407,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityEmailNotifier.java",
    "chars": 8711,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityMonkey.java",
    "chars": 3123,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityRule.java",
    "chars": 1363,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/conformity/ConformityRuleEngine.java",
    "chars": 2950,
    "preview": "/*\n *\n *  Copyright 2013 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/AbstractJanitor.java",
    "chars": 19637,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/DryRunnableJanitor.java",
    "chars": 895,
    "preview": "/*\n *\n *  Copyright 2017 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/DryRunnableJanitorException.java",
    "chars": 944,
    "preview": "/*\n *\n *  Copyright 2017 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/Janitor.java",
    "chars": 1389,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorCrawler.java",
    "chars": 1842,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorEmailBuilder.java",
    "chars": 1294,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorEmailNotifier.java",
    "chars": 11932,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorMonkey.java",
    "chars": 4688,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorResourceTracker.java",
    "chars": 2200,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/JanitorRuleEngine.java",
    "chars": 2351,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/janitor/Rule.java",
    "chars": 1319,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/resources/chaos/ChaosMonkeyResource.java",
    "chars": 10408,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/resources/janitor/JanitorMonkeyResource.java",
    "chars": 9813,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/tunable/TunableInstanceGroup.java",
    "chars": 1620,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/java/com/netflix/simianarmy/tunable/TunablyAggressiveChaosMonkey.java",
    "chars": 1947,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/main/resources/chaos.properties",
    "chars": 4534,
    "preview": "# The file contains the properties for Chaos Monkey.\n# see documentation at:\n# https://github.com/Netflix/SimianArmy/wik"
  },
  {
    "path": "src/main/resources/client.properties",
    "chars": 2856,
    "preview": "#####################################################################\n### Configure which client and context to use.\n###"
  },
  {
    "path": "src/main/resources/conformity.properties",
    "chars": 4238,
    "preview": "# let Conformity monkey run\nsimianarmy.conformity.enabled = true\n\n# dryrun mode, no email notification to the owner of n"
  },
  {
    "path": "src/main/resources/janitor.properties",
    "chars": 9707,
    "preview": "# see documentation at:\n# https://github.com/Netflix/SimianArmy/wiki/Configuration\n\n# By default Janitor Monkey wakes up"
  },
  {
    "path": "src/main/resources/log4j.properties",
    "chars": 258,
    "preview": "log4j.rootLogger=INFO, stdout\n\n# stdout\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.lay"
  },
  {
    "path": "src/main/resources/scripts/burncpu.sh",
    "chars": 275,
    "preview": "#!/bin/bash\n# Script for BurnCpu Chaos Monkey\n\ncat << EOF > /tmp/infiniteburn.sh\n#!/bin/bash\nwhile true;\n    do openssl "
  },
  {
    "path": "src/main/resources/scripts/burnio.sh",
    "chars": 217,
    "preview": "#!/bin/bash\n# Script for BurnIO Chaos Monkey\n\ncat << EOF > /tmp/loopburnio.sh\n#!/bin/bash\nwhile true;\ndo\n    dd if=/dev/"
  },
  {
    "path": "src/main/resources/scripts/faildns.sh",
    "chars": 180,
    "preview": "#!/bin/bash\n# Script for FailDns Chaos Monkey\n\n# Block all traffic on port 53\niptables -A INPUT -p tcp -m tcp --dport 53"
  },
  {
    "path": "src/main/resources/scripts/faildynamodb.sh",
    "chars": 698,
    "preview": "#!/bin/bash\n# Script for FailDynamoDb Chaos Monkey\n\n# Block well-known Amazon DynamoDB API endpoints\necho \"127.0.0.1 dyn"
  },
  {
    "path": "src/main/resources/scripts/failec2.sh",
    "chars": 643,
    "preview": "#!/bin/bash\n# Script for FailEc2 Chaos Monkey\n\n# Block well-known Amazon EC2 API endpoints\necho \"127.0.0.1 ec2.us-east-1"
  },
  {
    "path": "src/main/resources/scripts/fails3.sh",
    "chars": 648,
    "preview": "#!/bin/bash\n# Script for FailS3 Chaos Monkey\n\n# See http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region\n\ne"
  },
  {
    "path": "src/main/resources/scripts/filldisk.sh",
    "chars": 174,
    "preview": "#!/bin/bash\n# Script for FillDisk Chaos Monkey\n\n# 65 GB should be enough to fill up all EC2 root disks!\nnohup dd if=/dev"
  },
  {
    "path": "src/main/resources/scripts/killprocesses.sh",
    "chars": 219,
    "preview": "#!/bin/bash\n# Script for KillProcesses Chaos Monkey\n\ncat << EOF > /tmp/kill_loop.sh\n#!/bin/bash\nwhile true;\ndo\n    pkill"
  },
  {
    "path": "src/main/resources/scripts/networkcorruption.sh",
    "chars": 131,
    "preview": "#!/bin/bash\n# Script for NetworkCorruption Chaos Monkey\n\n# Corrupts 5% of packets\nsudo tc qdisc add dev eth0 root netem "
  },
  {
    "path": "src/main/resources/scripts/networklatency.sh",
    "chars": 161,
    "preview": "#!/bin/bash\n# Script for NetworkLatency Chaos Monkey\n\n# Adds 1000ms +- 500ms of latency to each packet\nsudo tc qdisc add"
  },
  {
    "path": "src/main/resources/scripts/networkloss.sh",
    "chars": 240,
    "preview": "#!/bin/bash\n# Script for NetworkLoss Chaos Monkey\n\n# Drops 7% of packets, with 25% correlation with previous packet loss"
  },
  {
    "path": "src/main/resources/scripts/nullroute.sh",
    "chars": 83,
    "preview": "#!/bin/bash\n# Script for NullRoute Chaos Monkey\n\nip route add blackhole 10.0.0.0/8\n"
  },
  {
    "path": "src/main/resources/simianarmy.properties",
    "chars": 1295,
    "preview": "# see documentation at:\n# https://github.com/Netflix/SimianArmy/wiki/Configuration\n\nsimianarmy.recorder.sdb.domain = SIM"
  },
  {
    "path": "src/main/resources/volumeTagging.properties",
    "chars": 782,
    "preview": "# see documentation at:\n# https://github.com/Netflix/SimianArmy/wiki/Configuration\n\n# The properties in this file are us"
  },
  {
    "path": "src/main/webapp/WEB-INF/web.xml",
    "chars": 989,
    "preview": "<web-app version=\"2.5\" xmlns=\"http://java.sun.com/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-in"
  },
  {
    "path": "src/test/java/com/netflix/simianarmy/TestMonkey.java",
    "chars": 1249,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/test/java/com/netflix/simianarmy/TestMonkeyContext.java",
    "chars": 8258,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  },
  {
    "path": "src/test/java/com/netflix/simianarmy/TestMonkeyRunner.java",
    "chars": 3317,
    "preview": "/*\n *\n *  Copyright 2012 Netflix, Inc.\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     "
  }
]

// ... and 89 more files (download for full content)

About this extraction

This page contains the full source code of the Netflix/SimianArmy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 289 files (1.3 MB), approximately 298.8k tokens, and a symbol index with 1950 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!