Skip to content

Commit f51613f

Browse files
authored
Merge pull request #469 from RachelTucker/SA-195
SA-195 & SA-196: Special cased commands with request payload of id list in python modules
2 parents e6674e6 + 23ce9c7 commit f51613f

File tree

17 files changed

+413
-5
lines changed

17 files changed

+413
-5
lines changed

ds3-autogen-python/src/main/java/com/spectralogic/ds3autogen/python/PythonCodeGenerator.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,20 @@ public BaseRequestGenerator getRequestGenerator(final Ds3Request ds3Request) {
232232
|| isBulkReplicateRequest(ds3Request)) {
233233
return new StringPayloadGenerator();
234234
}
235+
if (hasIdsRequestPayload(ds3Request)) {
236+
return getIdsRequestGenerator();
237+
}
235238
return new BaseRequestGenerator();
236239
}
237240

241+
/**
242+
* Retrieves the generator for the clear blob and mark blob commands
243+
*/
244+
@Override
245+
public BaseRequestGenerator getIdsRequestGenerator() {
246+
return new IdListRequestPayloadGenerator();
247+
}
248+
238249
/**
239250
* Retrieves the generator for amazon3 PutObject command
240251
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* ******************************************************************************
3+
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the "license" file accompanying this file.
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
* specific language governing permissions and limitations under the License.
13+
* ****************************************************************************
14+
*/
15+
16+
package com.spectralogic.ds3autogen.python.generators.request;
17+
18+
import com.google.common.collect.ImmutableList;
19+
import com.spectralogic.ds3autogen.api.models.Arguments;
20+
import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request;
21+
import com.spectralogic.ds3autogen.python.model.request.ConstructorParam;
22+
import com.spectralogic.ds3autogen.utils.collections.GuavaCollectors;
23+
import com.spectralogic.ds3autogen.utils.comparators.CustomArgumentComparator;
24+
25+
import static com.spectralogic.ds3autogen.python.helpers.PythonHelper.pythonIndent;
26+
import static com.spectralogic.ds3autogen.utils.Helper.camelToUnderscore;
27+
import static com.spectralogic.ds3autogen.utils.RequestConverterUtil.getNonVoidArgsFromParamList;
28+
29+
/**
30+
* Generates Python request handlers that take in a list of strings and marshals them into a list of ids.
31+
*/
32+
public class IdListRequestPayloadGenerator extends BaseRequestGenerator {
33+
34+
protected static final String PAYLOAD_NAME = "id_list";
35+
36+
/**
37+
* Gets the sorted list of required constructor parameters including the request payload
38+
*/
39+
@Override
40+
public ImmutableList<ConstructorParam> toRequiredConstructorParams(final Ds3Request ds3Request) {
41+
final ImmutableList.Builder<Arguments> builder = ImmutableList.builder();
42+
builder.addAll(getNonVoidArgsFromParamList(ds3Request.getRequiredQueryParams()));
43+
builder.addAll(getAssignmentArguments(ds3Request));
44+
builder.add(new Arguments("string", PAYLOAD_NAME));
45+
46+
return builder.build().stream()
47+
.sorted(new CustomArgumentComparator())
48+
.map(arg -> new ConstructorParam(camelToUnderscore(arg.getName()), false))
49+
.collect(GuavaCollectors.immutableList());
50+
}
51+
52+
/**
53+
* Gets the python code that handles processing the request payload and headers
54+
*/
55+
@Override
56+
public String getAdditionalContent(final Ds3Request ds3Request, final String requestName) {
57+
return "if " + PAYLOAD_NAME + " is not None:\n" +
58+
pythonIndent(3) + "if not (isinstance(cur_id, basestring) for cur_id in " + PAYLOAD_NAME + "):\n" +
59+
pythonIndent(4) + "raise TypeError(\n" +
60+
pythonIndent(5) + "'" + requestName + " should have request payload of type: list of strings')\n" +
61+
pythonIndent(3) + "xml_id_list = IdsList(" + PAYLOAD_NAME + ")\n" +
62+
pythonIndent(3) + "self.body = xmldom.tostring(xml_id_list.to_xml())\n";
63+
}
64+
}

ds3-autogen-python/src/main/kotlin/com/spectralogic/ds3autogen/python/PythonCodeGeneratorInterface.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request
2121
import com.spectralogic.ds3autogen.api.models.apispec.Ds3Type
2222
import com.spectralogic.ds3autogen.api.models.docspec.Ds3DocSpec
2323
import com.spectralogic.ds3autogen.python.generators.request.BaseRequestGenerator
24-
import com.spectralogic.ds3autogen.python.generators.request.RequestModelGenerator
2524
import com.spectralogic.ds3autogen.python.model.request.BaseRequest
2625
import freemarker.template.Configuration
2726
import freemarker.template.Template
@@ -40,6 +39,8 @@ interface PythonCodeGeneratorInterface {
4039

4140
fun getPutObjectRequestGenerator() : BaseRequestGenerator
4241

42+
fun getIdsRequestGenerator(): BaseRequestGenerator
43+
4344
fun getRequestGenerator(ds3Request: Ds3Request) : BaseRequestGenerator
4445

4546
fun toRequestModel(ds3Request: Ds3Request,

ds3-autogen-python/src/main/resources/tmpls/python/commands/all_commands.ftl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ from ds3network import *
1717
<#include "static_classes.ftl" />
1818

1919

20+
class IdsList(object):
21+
def __init__(self, id_list):
22+
for cur_id in id_list:
23+
if not isinstance(cur_id, basestring):
24+
raise TypeError("Ids should only contain strings")
25+
self.id_list = id_list
26+
27+
def to_xml(self):
28+
xml_id_list = xmldom.Element('Ids')
29+
for cur_id in self.id_list:
30+
xml_cur_id = xmldom.Element('Id')
31+
xml_cur_id.text = cur_id
32+
xml_id_list.append(xml_cur_id)
33+
return xml_id_list
34+
35+
2036
# Type Descriptors
2137

2238

ds3-autogen-python/src/test/java/com.spectralogic.ds3autogen.python/PythonCodeGenerator_Test.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ public void getRequestGenerator_Test() {
7272
assertThat(generator.getRequestGenerator(getGetBlobPersistence()), instanceOf(StringPayloadGenerator.class));
7373
assertThat(generator.getRequestGenerator(getReplicatePutJob()), instanceOf(StringPayloadGenerator.class));
7474

75+
assertThat(generator.getRequestGenerator(clearSuspectBlobAzureTargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
76+
assertThat(generator.getRequestGenerator(clearSuspectBlobDs3TargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
77+
assertThat(generator.getRequestGenerator(clearSuspectBlobPoolsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
78+
assertThat(generator.getRequestGenerator(clearSuspectBlobS3TargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
79+
assertThat(generator.getRequestGenerator(clearSuspectBlobTapesRequest()), instanceOf(IdListRequestPayloadGenerator.class));
80+
assertThat(generator.getRequestGenerator(markSuspectBlobAzureTargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
81+
assertThat(generator.getRequestGenerator(markSuspectBlobDs3TargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
82+
assertThat(generator.getRequestGenerator(markSuspectBlobPoolsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
83+
assertThat(generator.getRequestGenerator(markSuspectBlobS3TargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
84+
assertThat(generator.getRequestGenerator(markSuspectBlobTapesAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
85+
7586
assertThat(generator.getRequestGenerator(getRequestBulkGet()), instanceOf(ObjectsPayloadGenerator.class));
7687
assertThat(generator.getRequestGenerator(getRequestBulkPut()), instanceOf(ObjectsPayloadGenerator.class));
7788
assertThat(generator.getRequestGenerator(getRequestVerifyPhysicalPlacement()), instanceOf(ObjectsPayloadGenerator.class));

ds3-autogen-python/src/test/java/com.spectralogic.ds3autogen.python/PythonFunctionalTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,31 @@ public void headObjectRequest() throws TemplateModelException, IOException {
308308
//Test Client
309309
hasClient(ImmutableList.of(requestName), ds3Code);
310310
}
311+
312+
@Test
313+
public void clearSuspectBlobAzureTargetsRequest() throws IOException, TemplateModelException {
314+
final String requestName = "ClearSuspectBlobAzureTargetsSpectraS3Request";
315+
final FileUtils fileUtils = mock(FileUtils.class);
316+
final TestPythonGeneratedCode codeGenerator = new TestPythonGeneratedCode(fileUtils);
317+
318+
codeGenerator.generateCode(fileUtils, "/input/requests/clearSuspectBlobAzureTargets.xml");
319+
final String ds3Code = codeGenerator.getDs3Code();
320+
321+
CODE_LOGGER.logFile(ds3Code, FileTypeToLog.REQUEST);
322+
323+
final ImmutableList<String> optArgs = ImmutableList.of("force");
324+
final String requestPayload = "id_list";
325+
326+
hasRequestHandler(requestName, HttpVerb.DELETE, ImmutableList.of(), optArgs, ImmutableList.of(), requestPayload, ds3Code);
327+
328+
assertTrue(ds3Code.contains("if id_list is not None:\n" +
329+
" if not (isinstance(cur_id, basestring) for cur_id in id_list):\n" +
330+
" raise TypeError(\n" +
331+
" 'ClearSuspectBlobAzureTargetsSpectraS3Request should have request payload of type: list of strings')\n" +
332+
" xml_id_list = IdsList(id_list)\n" +
333+
" self.body = xmldom.tostring(xml_id_list.to_xml())"));
334+
335+
//Test Client
336+
hasClient(ImmutableList.of(requestName), ds3Code);
337+
}
311338
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* ******************************************************************************
3+
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the "license" file accompanying this file.
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
* specific language governing permissions and limitations under the License.
13+
* ****************************************************************************
14+
*/
15+
16+
package com.spectralogic.ds3autogen.python.generators.request;
17+
18+
import com.google.common.collect.ImmutableList;
19+
import com.spectralogic.ds3autogen.python.model.request.ConstructorParam;
20+
import com.spectralogic.ds3autogen.utils.collections.GuavaCollectors;
21+
import org.junit.Test;
22+
23+
import static com.spectralogic.ds3autogen.testutil.Ds3ModelFixtures.clearSuspectBlobAzureTargetsRequest;
24+
import static org.hamcrest.CoreMatchers.hasItem;
25+
import static org.hamcrest.CoreMatchers.is;
26+
import static org.junit.Assert.assertThat;
27+
28+
public class IdListRequestPayloadGenerator_Test {
29+
30+
private static final IdListRequestPayloadGenerator generator = new IdListRequestPayloadGenerator();
31+
32+
@Test
33+
public void getAdditionalContentTest() {
34+
final String expected = "if id_list is not None:\n" +
35+
" if not (isinstance(cur_id, basestring) for cur_id in id_list):\n" +
36+
" raise TypeError(\n" +
37+
" 'ClearSuspectBlobAzureTargetsSpectraS3Request should have request payload of type: list of strings')\n" +
38+
" xml_id_list = IdsList(id_list)\n" +
39+
" self.body = xmldom.tostring(xml_id_list.to_xml())\n";
40+
final String result = generator.getAdditionalContent(clearSuspectBlobAzureTargetsRequest(), "ClearSuspectBlobAzureTargetsSpectraS3Request");
41+
assertThat(result, is(expected));
42+
}
43+
44+
@Test
45+
public void toRequiredConstructorParamsTest() {
46+
final ImmutableList<ConstructorParam> reqParams = generator
47+
.toRequiredConstructorParams(clearSuspectBlobAzureTargetsRequest());
48+
49+
final ImmutableList<String> result = reqParams.stream()
50+
.map(ConstructorParam::toPythonCode)
51+
.collect(GuavaCollectors.immutableList());
52+
53+
assertThat(result.size(), is(1));
54+
assertThat(result, hasItem("id_list"));
55+
}
56+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<Data>
2+
<Contract>
3+
<RequestHandlers>
4+
<RequestHandler Classification="spectrads3" Name="com.spectralogic.s3.server.handler.reqhandler.spectrads3.degradation.ClearSuspectBlobAzureTargetsRequestHandler">
5+
<Request Action="BULK_DELETE" HttpVerb="DELETE" IncludeIdInPath="false" Resource="SUSPECT_BLOB_AZURE_TARGET" ResourceType="NON_SINGLETON">
6+
<OptionalQueryParams>
7+
<Param Name="Force" Type="void"/>
8+
</OptionalQueryParams>
9+
<RequiredQueryParams/>
10+
</Request>
11+
<ResponseCodes>
12+
<ResponseCode>
13+
<Code>204</Code>
14+
<ResponseTypes>
15+
<ResponseType Type="null"/>
16+
</ResponseTypes>
17+
</ResponseCode>
18+
<ResponseCode>
19+
<Code>400</Code>
20+
<ResponseTypes>
21+
<ResponseType Type="com.spectralogic.s3.server.domain.HttpErrorResultApiBean"/>
22+
</ResponseTypes>
23+
</ResponseCode>
24+
<ResponseCode>
25+
<Code>409</Code>
26+
<ResponseTypes>
27+
<ResponseType Type="com.spectralogic.s3.server.domain.HttpErrorResultApiBean"/>
28+
</ResponseTypes>
29+
</ResponseCode>
30+
</ResponseCodes>
31+
<Version>1.F51C99474F629A2CFD5CDB6BC5CB7C6D</Version>
32+
</RequestHandler>
33+
</RequestHandlers>
34+
</Contract>
35+
</Data>

ds3-autogen-python3/src/main/kotlin/com/spectralogic/ds3autogen/python3/Python3CodeGenerator.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ package com.spectralogic.ds3autogen.python3
1717

1818
import com.spectralogic.ds3autogen.python.PythonCodeGenerator
1919
import com.spectralogic.ds3autogen.python.generators.request.BaseRequestGenerator
20+
import com.spectralogic.ds3autogen.python3.generators.request.P3IdListRequestGenerator
2021
import com.spectralogic.ds3autogen.python3.generators.request.P3PutObjectRequestGenerator
2122
import freemarker.template.Configuration
2223
import freemarker.template.Template
2324

24-
class Python3CodeGenerator() : PythonCodeGenerator() {
25+
class Python3CodeGenerator : PythonCodeGenerator() {
2526

2627
/**
2728
* Retrieves the base command template used to generate the Python 3 ds3.py
@@ -36,4 +37,11 @@ class Python3CodeGenerator() : PythonCodeGenerator() {
3637
override fun getPutObjectRequestGenerator() : BaseRequestGenerator {
3738
return P3PutObjectRequestGenerator()
3839
}
40+
41+
/**
42+
* Retrieves the generator for the Python 3 clear blob and mark blob commands
43+
*/
44+
override fun getIdsRequestGenerator(): BaseRequestGenerator {
45+
return P3IdListRequestGenerator()
46+
}
3947
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* ******************************************************************************
3+
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the "license" file accompanying this file.
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
* specific language governing permissions and limitations under the License.
13+
* ****************************************************************************
14+
*/
15+
16+
package com.spectralogic.ds3autogen.python3.generators.request
17+
18+
import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request
19+
import com.spectralogic.ds3autogen.python.generators.request.IdListRequestPayloadGenerator
20+
import com.spectralogic.ds3autogen.python.helpers.PythonHelper.pythonIndent
21+
22+
/**
23+
* Creates the Python 3 request model for the clear blob and mark blob commands
24+
*/
25+
class P3IdListRequestGenerator : IdListRequestPayloadGenerator() {
26+
27+
/**
28+
* Gets the Python 3 code that handles processing the request payload and headers
29+
*/
30+
override fun getAdditionalContent(ds3Request: Ds3Request, requestName : String) : String {
31+
return "if $PAYLOAD_NAME is not None:\n" +
32+
pythonIndent(3) + "if not (isinstance(cur_id, str) for cur_id in $PAYLOAD_NAME):\n" +
33+
pythonIndent(4) + "raise TypeError(\n" +
34+
pythonIndent(5) + "'" + requestName + " should have request payload of type: list of strings')\n" +
35+
pythonIndent(3) + "xml_id_list = IdsList($PAYLOAD_NAME)\n" +
36+
pythonIndent(3) + "self.body = xmldom.tostring(xml_id_list.to_xml())\n"
37+
}
38+
}

0 commit comments

Comments
 (0)