diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-3bb4487.json b/.changes/next-release/bugfix-AWSSDKforJavav2-3bb4487.json new file mode 100644 index 00000000000..fe54526399c --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-3bb4487.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS IAM Policy Builder", + "contributor": "", + "description": "Fixed bug where actions were written instead of resources." +} diff --git a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicy.java b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicy.java index fd3b4d663b9..0fd0354a395 100644 --- a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicy.java +++ b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicy.java @@ -55,7 +55,7 @@ * Create a new IAM identity policy that allows a role to write items to an Amazon DynamoDB table. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam - * try (IamClient iam = IamClient.create()) { + * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * IamPolicy policy = * IamPolicy.builder() * .addStatement(IamStatement.builder() @@ -73,7 +73,7 @@ * Download the policy uploaded in the previous example and create a new policy with "read" access added to it. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam - * try (IamClient iam = IamClient.create()) { + * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * String policyArn = "arn:aws:iam::123456789012:policy/AllowWriteBookMetadata"; * GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn)); * diff --git a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReader.java b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReader.java index 92e6505548a..6c87957e52f 100644 --- a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReader.java +++ b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReader.java @@ -27,7 +27,7 @@ * Log the number of statements in a policy downloaded from IAM. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam - * try (IamClient iam = IamClient.create()) { + * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * String policyArn = "arn:aws:iam::123456789012:policy/AllowWriteBookMetadata"; * GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn)); * diff --git a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriter.java b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriter.java index 2b64ccfb2ba..faaffa73feb 100644 --- a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriter.java +++ b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriter.java @@ -28,7 +28,7 @@ * Create a new IAM identity policy that allows a role to write items to an Amazon DynamoDB table. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam - * try (IamClient iam = IamClient.create()) { + * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * IamPolicy policy = * IamPolicy.builder() * .addStatement(IamStatement.builder() diff --git a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/internal/DefaultIamPolicyWriter.java b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/internal/DefaultIamPolicyWriter.java index 553df49d3e1..b63021af221 100644 --- a/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/internal/DefaultIamPolicyWriter.java +++ b/services-custom/iam-policy-builder/src/main/java/software/amazon/awssdk/policybuilder/iam/internal/DefaultIamPolicyWriter.java @@ -143,7 +143,7 @@ private void writeStatement(JsonWriter writer, IamStatement statement) { writePrincipals(writer, "NotPrincipal", statement.notPrincipals()); writeValueArrayField(writer, "Action", statement.actions()); writeValueArrayField(writer, "NotAction", statement.notActions()); - writeValueArrayField(writer, "Resource", statement.actions()); + writeValueArrayField(writer, "Resource", statement.resources()); writeValueArrayField(writer, "NotResource", statement.notResources()); writeConditions(writer, statement.conditions()); writer.writeEndObject(); diff --git a/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReaderTest.java b/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReaderTest.java index 4b1f5d341b0..89112452d64 100644 --- a/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReaderTest.java +++ b/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyReaderTest.java @@ -23,12 +23,18 @@ import org.junit.jupiter.api.Test; class IamPolicyReaderTest { - private static final IamPrincipal PRINCIPAL_1 = IamPrincipal.ALL; - private static final IamPrincipal PRINCIPAL_2 = IamPrincipal.create("2", "*"); - private static final IamResource RESOURCE_1 = IamResource.create("1"); - private static final IamResource RESOURCE_2 = IamResource.create("2"); - private static final IamAction ACTION_1 = IamAction.create("1"); - private static final IamAction ACTION_2 = IamAction.create("2"); + private static final IamPrincipal PRINCIPAL_1 = IamPrincipal.create("P1", "*"); + private static final IamPrincipal PRINCIPAL_2 = IamPrincipal.create("P2", "*"); + private static final IamPrincipal NOT_PRINCIPAL_1 = IamPrincipal.create("NP1", "*"); + private static final IamPrincipal NOT_PRINCIPAL_2 = IamPrincipal.create("NP2", "*"); + private static final IamResource RESOURCE_1 = IamResource.create("R1"); + private static final IamResource RESOURCE_2 = IamResource.create("R2"); + private static final IamResource NOT_RESOURCE_1 = IamResource.create("NR1"); + private static final IamResource NOT_RESOURCE_2 = IamResource.create("NR2"); + private static final IamAction ACTION_1 = IamAction.create("A1"); + private static final IamAction ACTION_2 = IamAction.create("A2"); + private static final IamAction NOT_ACTION_1 = IamAction.create("NA1"); + private static final IamAction NOT_ACTION_2 = IamAction.create("NA2"); private static final IamCondition CONDITION_1 = IamCondition.create("1", "K1", "V1"); private static final IamCondition CONDITION_2 = IamCondition.create("1", "K2", "V1"); private static final IamCondition CONDITION_3 = IamCondition.create("1", "K2", "V2"); @@ -39,11 +45,11 @@ class IamPolicyReaderTest { .effect(ALLOW) .sid("Sid") .principals(asList(PRINCIPAL_1, PRINCIPAL_2)) - .notPrincipals(asList(PRINCIPAL_1, PRINCIPAL_2)) + .notPrincipals(asList(NOT_PRINCIPAL_1, NOT_PRINCIPAL_2)) .resources(asList(RESOURCE_1, RESOURCE_2)) - .notResources(asList(RESOURCE_1, RESOURCE_2)) + .notResources(asList(NOT_RESOURCE_1, NOT_RESOURCE_2)) .actions(asList(ACTION_1, ACTION_2)) - .notActions(asList(ACTION_1, ACTION_2)) + .notActions(asList(NOT_ACTION_1, NOT_ACTION_2)) .conditions(asList(CONDITION_1, CONDITION_2, CONDITION_3, CONDITION_4)) .build(); @@ -66,12 +72,12 @@ class IamPolicyReaderTest { IamStatement.builder() .effect(ALLOW) .sid("Sid") - .principals(singletonList(PRINCIPAL_1)) - .notPrincipals(singletonList(PRINCIPAL_1)) + .principals(singletonList(IamPrincipal.ALL)) + .notPrincipals(singletonList(IamPrincipal.ALL)) .resources(singletonList(RESOURCE_1)) - .notResources(singletonList(RESOURCE_1)) + .notResources(singletonList(NOT_RESOURCE_1)) .actions(singletonList(ACTION_1)) - .notActions(singletonList(ACTION_1)) + .notActions(singletonList(NOT_ACTION_1)) .conditions(singletonList(CONDITION_1)) .build(); @@ -85,17 +91,6 @@ class IamPolicyReaderTest { @Test public void readFullPolicyWorks() { - assertThat(READER.read("{\"Version\":\"Version\"," - + "\"Id\":\"Id\"," - + "\"Statement\":[" - + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"*\":\"*\",\"2\":\"*\"},\"NotPrincipal\":{\"*\":\"*\",\"2\":\"*\"},\"Action\":[\"1\",\"2\"],\"NotAction\":[\"1\",\"2\"],\"Resource\":[\"1\",\"2\"],\"NotResource\":[\"1\",\"2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}," - + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"*\":\"*\",\"2\":\"*\"},\"NotPrincipal\":{\"*\":\"*\",\"2\":\"*\"},\"Action\":[\"1\",\"2\"],\"NotAction\":[\"1\",\"2\"],\"Resource\":[\"1\",\"2\"],\"NotResource\":[\"1\",\"2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}" - + "]}")) - .isEqualTo(FULL_POLICY); - } - - @Test - public void prettyWriteFullPolicyWorks() { assertThat(READER.read("{\n" + " \"Version\" : \"Version\",\n" + " \"Id\" : \"Id\",\n" @@ -103,17 +98,17 @@ public void prettyWriteFullPolicyWorks() { + " \"Sid\" : \"Sid\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : {\n" - + " \"*\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"P1\" : \"*\",\n" + + " \"P2\" : \"*\"\n" + " },\n" + " \"NotPrincipal\" : {\n" - + " \"*\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"NP1\" : \"*\",\n" + + " \"NP2\" : \"*\"\n" + " },\n" - + " \"Action\" : [ \"1\", \"2\" ],\n" - + " \"NotAction\" : [ \"1\", \"2\" ],\n" - + " \"Resource\" : [ \"1\", \"2\" ],\n" - + " \"NotResource\" : [ \"1\", \"2\" ],\n" + + " \"Action\" : [ \"A1\", \"A2\" ],\n" + + " \"NotAction\" : [ \"NA1\", \"NA2\" ],\n" + + " \"Resource\" : [ \"R1\", \"R2\" ],\n" + + " \"NotResource\" : [ \"NR1\", \"NR2\" ],\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\",\n" @@ -127,17 +122,17 @@ public void prettyWriteFullPolicyWorks() { + " \"Sid\" : \"Sid\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : {\n" - + " \"*\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"P1\" : \"*\",\n" + + " \"P2\" : \"*\"\n" + " },\n" + " \"NotPrincipal\" : {\n" - + " \"*\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"NP1\" : \"*\",\n" + + " \"NP2\" : \"*\"\n" + " },\n" - + " \"Action\" : [ \"1\", \"2\" ],\n" - + " \"NotAction\" : [ \"1\", \"2\" ],\n" - + " \"Resource\" : [ \"1\", \"2\" ],\n" - + " \"NotResource\" : [ \"1\", \"2\" ],\n" + + " \"Action\" : [ \"A1\", \"A2\" ],\n" + + " \"NotAction\" : [ \"NA1\", \"NA2\" ],\n" + + " \"Resource\" : [ \"R1\", \"R2\" ],\n" + + " \"NotResource\" : [ \"NR1\", \"NR2\" ],\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\",\n" @@ -153,7 +148,7 @@ public void prettyWriteFullPolicyWorks() { } @Test - public void writeMinimalPolicyWorks() { + public void readMinimalPolicyWorks() { assertThat(READER.read("{\n" + " \"Version\" : \"Version\",\n" + " \"Statement\" : {\n" @@ -164,7 +159,7 @@ public void writeMinimalPolicyWorks() { } @Test - public void singleElementListsAreWrittenAsNonArrays() { + public void singleElementListsAreSupported() { assertThat(READER.read("{\n" + " \"Version\" : \"Version\",\n" + " \"Statement\" : {\n" @@ -172,10 +167,10 @@ public void singleElementListsAreWrittenAsNonArrays() { + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : \"*\",\n" + " \"NotPrincipal\" : \"*\",\n" - + " \"Action\" : \"1\",\n" - + " \"NotAction\" : \"1\",\n" - + " \"Resource\" : \"1\",\n" - + " \"NotResource\" : \"1\",\n" + + " \"Action\" : \"A1\",\n" + + " \"NotAction\" : \"NA1\",\n" + + " \"Resource\" : \"R1\",\n" + + " \"NotResource\" : \"NR1\",\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\"\n" diff --git a/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriterTest.java b/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriterTest.java index 8e2c6811b66..9b0a932fa62 100644 --- a/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriterTest.java +++ b/services-custom/iam-policy-builder/src/test/java/software/amazon/awssdk/policybuilder/iam/IamPolicyWriterTest.java @@ -23,12 +23,18 @@ import org.junit.jupiter.api.Test; class IamPolicyWriterTest { - private static final IamPrincipal PRINCIPAL_1 = IamPrincipal.create("1", "*"); - private static final IamPrincipal PRINCIPAL_2 = IamPrincipal.create("2", "*"); - private static final IamResource RESOURCE_1 = IamResource.create("1"); - private static final IamResource RESOURCE_2 = IamResource.create("2"); - private static final IamAction ACTION_1 = IamAction.create("1"); - private static final IamAction ACTION_2 = IamAction.create("2"); + private static final IamPrincipal PRINCIPAL_1 = IamPrincipal.create("P1", "*"); + private static final IamPrincipal PRINCIPAL_2 = IamPrincipal.create("P2", "*"); + private static final IamPrincipal NOT_PRINCIPAL_1 = IamPrincipal.create("NP1", "*"); + private static final IamPrincipal NOT_PRINCIPAL_2 = IamPrincipal.create("NP2", "*"); + private static final IamResource RESOURCE_1 = IamResource.create("R1"); + private static final IamResource RESOURCE_2 = IamResource.create("R2"); + private static final IamResource NOT_RESOURCE_1 = IamResource.create("NR1"); + private static final IamResource NOT_RESOURCE_2 = IamResource.create("NR2"); + private static final IamAction ACTION_1 = IamAction.create("A1"); + private static final IamAction ACTION_2 = IamAction.create("A2"); + private static final IamAction NOT_ACTION_1 = IamAction.create("NA1"); + private static final IamAction NOT_ACTION_2 = IamAction.create("NA2"); private static final IamCondition CONDITION_1 = IamCondition.create("1", "K1", "V1"); private static final IamCondition CONDITION_2 = IamCondition.create("2", "K1", "V1"); private static final IamCondition CONDITION_3 = IamCondition.create("1", "K2", "V1"); @@ -39,11 +45,11 @@ class IamPolicyWriterTest { .effect(ALLOW) .sid("Sid") .principals(asList(PRINCIPAL_1, PRINCIPAL_2)) - .notPrincipals(asList(PRINCIPAL_1, PRINCIPAL_2)) + .notPrincipals(asList(NOT_PRINCIPAL_1, NOT_PRINCIPAL_2)) .resources(asList(RESOURCE_1, RESOURCE_2)) - .notResources(asList(RESOURCE_1, RESOURCE_2)) + .notResources(asList(NOT_RESOURCE_1, NOT_RESOURCE_2)) .actions(asList(ACTION_1, ACTION_2)) - .notActions(asList(ACTION_1, ACTION_2)) + .notActions(asList(NOT_ACTION_1, NOT_ACTION_2)) .conditions(asList(CONDITION_1, CONDITION_2, CONDITION_3, CONDITION_4)) .build(); @@ -69,9 +75,9 @@ class IamPolicyWriterTest { .principals(singletonList(IamPrincipal.ALL)) .notPrincipals(singletonList(IamPrincipal.ALL)) .resources(singletonList(RESOURCE_1)) - .notResources(singletonList(RESOURCE_1)) + .notResources(singletonList(NOT_RESOURCE_1)) .actions(singletonList(ACTION_1)) - .notActions(singletonList(ACTION_1)) + .notActions(singletonList(NOT_ACTION_1)) .conditions(singletonList(CONDITION_1)) .build(); @@ -95,8 +101,8 @@ public void writeFullPolicyWorks() { .isEqualTo("{\"Version\":\"Version\"," + "\"Id\":\"Id\"," + "\"Statement\":[" - + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"1\":\"*\",\"2\":\"*\"},\"NotPrincipal\":{\"1\":\"*\",\"2\":\"*\"},\"Action\":[\"1\",\"2\"],\"NotAction\":[\"1\",\"2\"],\"Resource\":[\"1\",\"2\"],\"NotResource\":[\"1\",\"2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}," - + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"1\":\"*\",\"2\":\"*\"},\"NotPrincipal\":{\"1\":\"*\",\"2\":\"*\"},\"Action\":[\"1\",\"2\"],\"NotAction\":[\"1\",\"2\"],\"Resource\":[\"1\",\"2\"],\"NotResource\":[\"1\",\"2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}" + + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"P1\":\"*\",\"P2\":\"*\"},\"NotPrincipal\":{\"NP1\":\"*\",\"NP2\":\"*\"},\"Action\":[\"A1\",\"A2\"],\"NotAction\":[\"NA1\",\"NA2\"],\"Resource\":[\"R1\",\"R2\"],\"NotResource\":[\"NR1\",\"NR2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}," + + "{\"Sid\":\"Sid\",\"Effect\":\"Allow\",\"Principal\":{\"P1\":\"*\",\"P2\":\"*\"},\"NotPrincipal\":{\"NP1\":\"*\",\"NP2\":\"*\"},\"Action\":[\"A1\",\"A2\"],\"NotAction\":[\"NA1\",\"NA2\"],\"Resource\":[\"R1\",\"R2\"],\"NotResource\":[\"NR1\",\"NR2\"],\"Condition\":{\"1\":{\"K1\":\"V1\",\"K2\":[\"V1\",\"V2\"]},\"2\":{\"K1\":\"V1\"}}}" + "]}"); } @@ -110,17 +116,17 @@ public void prettyWriteFullPolicyWorks() { + " \"Sid\" : \"Sid\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : {\n" - + " \"1\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"P1\" : \"*\",\n" + + " \"P2\" : \"*\"\n" + " },\n" + " \"NotPrincipal\" : {\n" - + " \"1\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"NP1\" : \"*\",\n" + + " \"NP2\" : \"*\"\n" + " },\n" - + " \"Action\" : [ \"1\", \"2\" ],\n" - + " \"NotAction\" : [ \"1\", \"2\" ],\n" - + " \"Resource\" : [ \"1\", \"2\" ],\n" - + " \"NotResource\" : [ \"1\", \"2\" ],\n" + + " \"Action\" : [ \"A1\", \"A2\" ],\n" + + " \"NotAction\" : [ \"NA1\", \"NA2\" ],\n" + + " \"Resource\" : [ \"R1\", \"R2\" ],\n" + + " \"NotResource\" : [ \"NR1\", \"NR2\" ],\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\",\n" @@ -134,17 +140,17 @@ public void prettyWriteFullPolicyWorks() { + " \"Sid\" : \"Sid\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : {\n" - + " \"1\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"P1\" : \"*\",\n" + + " \"P2\" : \"*\"\n" + " },\n" + " \"NotPrincipal\" : {\n" - + " \"1\" : \"*\",\n" - + " \"2\" : \"*\"\n" + + " \"NP1\" : \"*\",\n" + + " \"NP2\" : \"*\"\n" + " },\n" - + " \"Action\" : [ \"1\", \"2\" ],\n" - + " \"NotAction\" : [ \"1\", \"2\" ],\n" - + " \"Resource\" : [ \"1\", \"2\" ],\n" - + " \"NotResource\" : [ \"1\", \"2\" ],\n" + + " \"Action\" : [ \"A1\", \"A2\" ],\n" + + " \"NotAction\" : [ \"NA1\", \"NA2\" ],\n" + + " \"Resource\" : [ \"R1\", \"R2\" ],\n" + + " \"NotResource\" : [ \"NR1\", \"NR2\" ],\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\",\n" @@ -179,10 +185,10 @@ public void singleElementListsAreWrittenAsNonArrays() { + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : \"*\",\n" + " \"NotPrincipal\" : \"*\",\n" - + " \"Action\" : \"1\",\n" - + " \"NotAction\" : \"1\",\n" - + " \"Resource\" : \"1\",\n" - + " \"NotResource\" : \"1\",\n" + + " \"Action\" : \"A1\",\n" + + " \"NotAction\" : \"NA1\",\n" + + " \"Resource\" : \"R1\",\n" + + " \"NotResource\" : \"NR1\",\n" + " \"Condition\" : {\n" + " \"1\" : {\n" + " \"K1\" : \"V1\"\n"