Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am working on a gradle plugin (i dont know groovy, and just started using gradle) that integrates with Asgard (from netflix). I want my extension object to look like this for the user:

asgard {
  url = "http://asgard"
  regions {
    "us-east-1" {
      autoScaling {
        {
          devPhase = "test"
          min = 3
          max = 6
          availabilityZones = ["us-east-1a", "us-east-1b", "us-east-1c"]
          ami = "Base AMI 2013-07-11"
          instanceType = "m3.xlarge"
          securityGroups = ["base", "test-application"]
        }
      }
    }
  }
}

Or something close to that. I have been able to get close to this by making autoScaling a List, but when ever i try to get a property from that class it seems to return a dynamic property and never the value. Here is the below starter plugin:

import org.gradle.internal.reflect.Instantiator

class AsgardPlugin implements Plugin<Project> {
  void apply(Project project) {
    project.extensions.create("asgard", AsgardPluginExtension, project)
    project.asgard.extensions.regions = project.container(AsgardRegion) {String name ->
      AsgardRegion region = project.gradle.services.get(Instantiator).newInstance(AsgardRegion, name)
      assert region instanceof ExtensionAware

      region.extensions.add("autoScaling", project.container(AsgardAutoScaling))

      return region
    }


    project.task('displayConfigs') << {
      if(project.asgard.applicationName == null) project.asgard.applicationName = project.name
      println "Asgard URL $project.asgard.url"
      println "Application name $project.asgard.applicationName"
      println "Runs on regions..."
      project.asgard.regions.each() {region ->
        println "\tRegion $region.name"
        println "\tAutoScaling groups..."
        region.autoScaling.each() {asg ->
          println "\t\tdevPhase $asg"
          println "\t\tdevPhase $asg.devPhase"
          println "\t\tdevPhase $asg.get('devPhase')"
        }
      }
    }
  }
}

class AsgardPluginExtension {
  String url = "http://asgard.sisa.samsung.com"
  String applicationName

  AsgardPluginExtension(Project project) {
    applicationName = project.name
  }
}

class AsgardRegion {
  def String name
  List<AsgardAutoScaling> autoScaling
  AsgardRegion(String name) { this.name = name }
}

class AsgardAutoScaling {
  String devPhase
  int min
  int max
  List<String> availabilityZones
  String ami
  String instanceType
  String sshKey
  List<String> securityGroups
}

When I run the task, this is what I see in the logs:

$  ./gradlew displayConfigs
:displayConfigs
Asgard URL http://asgard
Application name gradle-asgard-plugin
Runs on regions...
        Region us-east-1
        AutoScaling groups...
Creating properties on demand (a.k.a. dynamic properties) has been deprecated and is scheduled to be removed in Gradle 2.0. Please read http://gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html for information on the replacement for dynamic properties.
Deprecated dynamic property: "devPhase" on "AsgardRegion_Decorated@65087be0", value: "test".
Deprecated dynamic property: "min" on "AsgardRegion_Decorated@65087be0", value: "3".
Deprecated dynamic property: "max" on "AsgardRegion_Decorated@65087be0", value: "6".
Deprecated dynamic property: "availabilityZones" on "AsgardRegion_Decorated@65087be0", value: "[us-east-1a, us-east-1...".
Deprecated dynamic property: "ami" on "AsgardRegion_Decorated@65087be0", value: "Base AMI 2013-07-11".
Deprecated dynamic property: "instanceType" on "AsgardRegion_Decorated@65087be0", value: "m3.xlarge".
Deprecated dynamic property: "securityGroups" on "AsgardRegion_Decorated@65087be0", value: "[base, test-application]".
                devPhase
                devPhase test
                devPhase AsgardRegion_Decorated@14860315('devPhase')

BUILD SUCCESSFUL

Total time: 1.996 secs

Am I going about this all wrong? If not how can I get the value from the dynamic property (tried get and value, but those don't seem to work).

Thanks for your time reading this.

share|improve this question

1 Answer

Some hints:

  • There is no need to add an autoScaling extension to region because the AsgardRegion class already has an autoScaling property. You just need to initialize that property and perhaps add a void autoScaling(Closure closure) { project.configure(autoScaling, closure) } convenience method to support the autoScaling { ... } syntax.

  • project.container creates a NamedDomainObjectContainer. The literal syntax for this container is someName { ... }; otherName { ... }. There is no "plain list" syntax.

  • Your test code sets devPhase etc. for the autoScaling container, which doesn't have these properties. That's why you get the dynamic properties warnings. The innermost { ... } is a block (not a closure) and is redundant.

To solve the list problem, either define a name property for AsgardAutoScaling and use the regular NamedDomainObjectContainer literal syntax, or don't use NamedDomainObjectContainer and implement your own syntax. For example, you could declare an autoScaling method on AsgardRegion that accepts a closure, creates an instance of AsgardAutoScaling, and adds it to the list.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.