How to define a Map<String,CustomObject> in build.gradle - gradle

I have a plugin as below
class AbstractConfigExtension {
public static final String NAME = "abstract_extension"
Project project
// Configuration extension properties
String service
String substrate
String region
String group
String pod
Map<String,InstanceGridDetails> instanceGridDetails = new HashMap<String,InstanceGridDetails>()
// new HashMap<String,String>()
List<String> tags = new ArrayList<>()
List<String> instances = ["i01"]
int numInstances = 1
boolean generateServiceFiles = true
}
I have a different class called InstanceGridDetails.groovy
class InstanceGridDetails {
// Grid Properties
String grid
String dsName
String ddName
public AcdsInstanceGridDetails () {
}
String getGrid() {
return this.grid
}
void grid(String grid) {
this.grid = grid
}
String dsName() {
return this.dsName
}
void dsName(String dsName) {
this.dsName = dsName
}
String ddName() {
return this.ddName
}
void ddName(String ddName) {
this.ddName = ddName
}
}
This is called as a plugin using the build.gradle as below
apply plugin: 'java'
apply plugin: HoconConfigPlugin
apply plugin: GriddableCaacRpmPlugin
abstract_extension {
service "relay"
substrate "1p"
region "xrd"
instanceGridDetails = ["i01": InstanceGridDetails { gridName "grid1"
dsName "ds1"
ddName "dd1"} ]
numInstances 1
tags = ["medium_mem"]
}
when I am doing as above I am getting the issue as below
FAILURE: Build failed with an exception.
Where: Build file 'config-packages/service-cfg-1p-xrd/build.gradle'
line: 13
What went wrong: A problem occurred evaluating project ':config-packages:service-cfg-1p-xrd'.
Could not find method InstanceGridDetails() for arguments [build_b1plunv4uhm1dpn66jee47jiz$_run_closure1$_closure2#25cf3fbf] on
object of type AbstractConfigExtension.

Your constructor is still called AcdsInstanceGridDetails while your class is called InstanceGridDetails. They should have the same name.
Try replacing all occurrences of AcdsInstanceGridDetails with InstanceGridDetails

Related

Swashbuckle not generating example xml correctly for array\list properties

It seems swashbuckle\swagger-ui (5.6 - using swagger-ui) does not generate example XML correctly when the model has a property that is a list.
To see this issue:
1 - Create an empty webapi project (I'm using asp.net)
2 - Add a couple of example models (I went with Customer + Order for testing)
public class Customer
{
public string AccountNumber { get; set; }
[XmlArray("Orders"),XmlArrayItem("Order")]
public List<Order> Orders { get;set; }
}
public class Order
{
public string OrderNumber { get;set; }
}
3 - Create a controller using FromBody to bind to model
public class CustomerController : ApiController
{
public void Post([FromBody]Customer customer)
{
customer.ToString();
}
}
4 - Change web api config to allow simple XML
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.XmlFormatter.UseXmlSerializer = true; //ADD THIS
}
}
5 - Run site and using /swagger ui change parameter content type to xml and select example model. You will find the example is as follows.
<?xml version="1.0"?>
<Customer>
<AccountNumber>string</AccountNumber>
<Orders>
<OrderNumber>string</OrderNumber>
</Orders>
</Customer>
6 - Submit this with a breakpoint on the customer.ToString() line in the controller and you will find the Orders collection is empty
7 - Modify the XML in swagger-ui to the following and submit:
<?xml version="1.0"?>
<Customer>
<AccountNumber>string</AccountNumber>
<Orders>
<Order><OrderNumber>string</OrderNumber></Order>
</Orders>
</Customer>
8 - The Customer.Orders collection is now correctly populated.
What is the best way to fix or workaround this in Swashbuckle?
(There are a few discussions around this and whether it's a bug in swagger-ui or Swashbuckle, but I'm specifically interested in working around it using Swashbuckle)
I have found the following works:
1 - Add an implementation of ISchemaFilter
internal class ApplySchemaVendorExtensions : ISchemaFilter
{
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
// Fix issues with xml array examples not generating correctly
if (!type.IsValueType)
{
schema.xml = new Xml { name = type.Name };
if(schema.properties != null)
{
foreach (var property in schema.properties)
{
//Array property, which wraps its elements
if (property.Value.type == "array")
{
property.Value.xml = new Xml
{
name = $"{property.Key}",
wrapped = true
};
}
}
}
}
}
}
2 - Comment this line into SwaggerConfig.cs
c.SchemaFilter<ApplySchemaVendorExtensions>();
Repeat the test in the Question and the example XML now works directly. As always I'm curious if there's a better solution...
EDIT: Actually this oddly works in the original project I have this issue, but in the small reproduction project for this Quesion it behaves slightly differently! I will edit this answer when I find why...
Thanks to #mutex, but I found that I needed to make another adjustment to it:
internal class SwaggerFixArraysInXmlFilter : Swashbuckle.Swagger.ISchemaFilter
{
// this fixes a Swagger bug that wasn't generating correct XML elements around List<> or array[] types
public void Apply(Swashbuckle.Swagger.Schema schema, Swashbuckle.Swagger.SchemaRegistry schemaRegistry, System.Type type)
{
// Fix issues with xml array examples not generating correctly
if (!type.IsValueType)
{
schema.xml = new Swashbuckle.Swagger.Xml { name = type.Name };
if (schema.properties != null)
{
foreach (var property in schema.properties)
{
//Array property, which wraps its elements
if (property.Value.type == "array")
{
property.Value.xml = new Swashbuckle.Swagger.Xml
{
name = $"{property.Key}",
wrapped = true
};
property.Value.items.xml = new Swashbuckle.Swagger.Xml
{
name = $"{property.Value.items.type}",
wrapped = true
};
}
}
}
}
}
}
Thanks to #Abacus, but I found that I needed to make another adjustment to it. (String is not a ValueType, so it was renaming any string value to <String>string</String>... May have something to do with .NET Core 3.1)
internal class SwaggerFixArraysInXmlFilter : Swashbuckle.Swagger.ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
Type type = context.Type;
// Fix issues with xml array examples not generating correctly
if (!type.IsValueType && type.Name != "String")
{
schema.Xml = new OpenApiXml { Name = type.Name };
if (schema.Properties != null)
{
foreach (var property in schema.Properties)
{
//Array property, which wraps its elements
if (property.Value.Type == "array")
{
property.Value.Xml = new OpenApiXml
{
Name = $"{property.Key}",
Wrapped = true
};
property.Value.Items.Xml = new OpenApiXml
{
Name = $"{property.Value.Items.Type}",
Wrapped = true
};
}
}
}
}
}
If you are using .Net Core 2.2 with Swagger v5, you will need the below code set
internal class SwaggerFixArraysInXmlFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
Type type = context.Type;
// Fix issues with xml array examples not generating correctly
if (!type.IsValueType)
{
schema.Xml = new OpenApiXml { Name = type.Name };
if (schema.Properties != null)
{
foreach (var property in schema.Properties)
{
//Array property, which wraps its elements
if (property.Value.Type == "array")
{
property.Value.Xml = new OpenApiXml
{
Name = $"{property.Key}",
Wrapped = true
};
property.Value.Items.Xml = new OpenApiXml
{
Name = $"{property.Value.Items.Type}",
Wrapped = true
};
}
}
}
}
}
}

Can I override/delegate assignment operator?

I began learn Groovy, and faced the challenge.
I have this code, that stores meta-data to object:
class Meta {
final MetaItem name
final MetaItem description
// ...
// And more fields with type MetaItem
// ...
Meta() {
name = new MetaItem("name")
description = new MetaItem("description")
}
void setName(String name) {
this.name.value = name
}
String getName() {
return this.name.value
}
void setDescription(String description) {
this.description.value = description
}
String getDescription() {
return this.description.value
}
// ...
// And more methods. Two for each field
// ...
}
class MetaItem {
private final def id
def value
MetaItem(String id) {
this.id = id
}
}
// Validating
def meta = new Meta()
assert meta.name == null
assert meta.description == null
meta.with {
name = "Name"
description = "Desc"
}
assert meta.name == "Name"
assert meta.description == "Desc"
print "Success!"
As you can see from the code, it increases quicly in volumes when new fields are added, because for each field you need to add two methods. Can this somehow be optimized? Redirect the assignment operation from object to his member. I've looked on Delegate, but this is not what I need.
P.S. I can't use access by .value because this class is used in Gradle extension and I need to configure it like this:
myExtension {
meta {
name = "Name"
description = "Desc"
// And many others
}
}
P.P.S. Sorry for my bad english, it's not my first language

Custom fields with FormBuilder in the Microsoft Bot Framework - not working

I tried this solution: Custom fields with FormBuilder in the Microsoft Bot Framework
But failed to get it working....The problem I encountered is that when I assign the base.Form = value, the _prompt in the _field gets a default recognizer, and it won't get overriden in the next line's SetRecognizer call, that only replaces the _field's recognizer.
However the matching process uses the _prompt's recognizer internally ( ? ).
Here is my code:
public class LuisIntentRecognizer<T> : RecognizePrimitive<T>
where T : class
{
public LuisIntentRecognizer(IField<T> field, string luisModelID, string luisSubscriptionKey)
: base(field)
{
_luisModelID = luisModelID;
_luisSubscriptionKey = luisSubscriptionKey;
}
public override DescribeAttribute ValueDescription(object value)
{
return new DescribeAttribute((string)value);
}
public override IEnumerable<string> ValidInputs(object value)
{
yield return (string)value;
}
public override TermMatch Parse(string input)
{
TermMatch result = null;
if (!string.IsNullOrWhiteSpace(input))
{
var luisModel = new LuisModelAttribute(_luisModelID, _luisSubscriptionKey);
var luisService = new LuisService(luisModel);
var luisResult = luisService.QueryAsync(input).Result; // TODO refactor somehow to async
var winner = luisResult.Intents.MaxBy(i => i.Score ?? 0d);
if (winner != null && !string.IsNullOrEmpty(winner.Intent))
{
result = new TermMatch(0, winner.Intent.Length, 0.0, winner.Intent);
}
else
{
result = new TermMatch(0, input.Length, 0.0, input);
}
}
return result;
}
public override string Help(T state, object defaultValue)
{
var prompt = new Prompter<T>(_field.Template(TemplateUsage.StringHelp), _field.Form, null);
var args = HelpArgs(state, defaultValue);
return prompt.Prompt(state, _field.Name, args.ToArray()).Prompt;
}
private string _luisModelID;
private string _luisSubscriptionKey;
}
public class LuisIntentField<T> : FieldReflector<T>
where T : class
{
public LuisIntentField(string name, string luisModelID, string luisSubscriptionKey, bool ignoreAnnotations = false)
: base(name, ignoreAnnotations)
{
_luisModelID = luisModelID;
_luisSubscriptionKey = luisSubscriptionKey;
}
public override IForm<T> Form
{
set
{
base.Form = value;
base.SetRecognizer(new LuisIntentRecognizer<T>(this, _luisModelID, _luisSubscriptionKey));
}
}
private string _luisModelID;
private string _luisSubscriptionKey;
}
Could anyone get it working?
Thanks
It seems to be a bug in the framework indeed: https://github.com/Microsoft/BotBuilder/issues/879

Spring.Caching.AspNetCache - Condition based on ReturnValue - Condition in Spring Expression Language

I use Cache Aspect with ASP.NET Cache. I need create condition based on ReturnValue.
I simplified my problem. I use CacheResult aspect on method wich return simple POCO object.
Here is definition:
public class MyData
{
public string MyProperty { get; set; }
}
public class MyResponse
{
public int MyId { get; set; }
public MyData [] Result { get; set; }
}
I need create condition for cache - Cache result only if MyResponse.MyData.Lenght is bigger then batch limit.
[CacheResult("AspNetCache", "'MyResponse.MyId=' + #id",
Condition = "MyResponse.Result.Length > #batchLimit")]
public MyResponse GetResponse(int id, int batchLimit)
{
Thread.Sleep(5000);
return new MyResponse
{
MyId = 1,
Result =
new MyData[]
{
new MyData {MyProperty = "A"}, new MyData {MyProperty = "B"},
new MyData {MyProperty = "C"},
}
};
}
I tried this definition of condition:
Condition = "MyResponse.Result.Length > #batchLimit"
I got this error:
'MyResponse' node cannot be resolved for the specified context
[Sample.MyResponse].
So I tried second version:
Condition = "'MyResponse.Result.Length' > #batchLimit"
Finished with error:
Cannot compare instances of [System.String] and [System.Int32] because they cannot be coerced to the same type.
I google it I can use keyword ReturnValue something like this:
Condition = "#ReturnValue != null"
But I don't know how I can access to MyResponse.MyData.Length.
the context for the evaluation of the condition expression is the return value, so just do this:
Condition = "Result.Length > #batchLimit"
equivalent to
Condition = "#root.Result.Length > #batchLimit"

Why would running Pex Explorations result in ignoring a previously Pex-generated test method?

Code being tested:
public class TestReader
{
public string Content { get; private set; }
public void LoadFile(string fileName)
{
var content = FileSystem.ReadAllText(fileName);
if (!content.StartsWith("test"))
throw new ArgumentException("invalid file");
this.Content = content;
}
}
public static class FileSystem
{
public static string ReadAllText(string fileName)
{
return File.ReadAllText(fileName);
}
}
Pex method in test project:
[PexMethod]
public void CheckValidFileWithPex(string content)
{
// arrange
var fileName = "test.txt";
Moles_Example.Moles.MFileSystem.ReadAllTextString =
delegate(string f)
{
Assert.IsTrue(f == fileName); return content;
};
// act
var test = new TestReader();
test.LoadFile(fileName);
// assert
Assert.AreEqual(content, test.Content);
}
When I first run "Pex Explorations" on CheckValidFileWithPex(string content), five test methods are generated with the following values for content:
null
""
"\0\0\0\0"
"test"
"\0\0\0\0\0"
However, if I run "Pex Explorations" again, no changes made to the generated tests, existing test project code, or main project prior to second execution, then only 4 tests are listed as generated and the test input from item 3 ("\0\0\0\0") is missing.
The source code of the Pex-generated test file still has a test method for this case, but I do not understand why this case is not listed in Pex Exploration Results.
Thank you for your insight.

Resources