Skip to content

Commit

Permalink
Special cased commands with request payload of id list in python and …
Browse files Browse the repository at this point in the history
…python 3 modules
  • Loading branch information
RachelTucker committed Mar 12, 2018
1 parent e6674e6 commit 23ce9c7
Show file tree
Hide file tree
Showing 17 changed files with 413 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,20 @@ public BaseRequestGenerator getRequestGenerator(final Ds3Request ds3Request) {
|| isBulkReplicateRequest(ds3Request)) {
return new StringPayloadGenerator();
}
if (hasIdsRequestPayload(ds3Request)) {
return getIdsRequestGenerator();
}
return new BaseRequestGenerator();
}

/**
* Retrieves the generator for the clear blob and mark blob commands
*/
@Override
public BaseRequestGenerator getIdsRequestGenerator() {
return new IdListRequestPayloadGenerator();
}

/**
* Retrieves the generator for amazon3 PutObject command
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* ******************************************************************************
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file.
* This file 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.spectralogic.ds3autogen.python.generators.request;

import com.google.common.collect.ImmutableList;
import com.spectralogic.ds3autogen.api.models.Arguments;
import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request;
import com.spectralogic.ds3autogen.python.model.request.ConstructorParam;
import com.spectralogic.ds3autogen.utils.collections.GuavaCollectors;
import com.spectralogic.ds3autogen.utils.comparators.CustomArgumentComparator;

import static com.spectralogic.ds3autogen.python.helpers.PythonHelper.pythonIndent;
import static com.spectralogic.ds3autogen.utils.Helper.camelToUnderscore;
import static com.spectralogic.ds3autogen.utils.RequestConverterUtil.getNonVoidArgsFromParamList;

/**
* Generates Python request handlers that take in a list of strings and marshals them into a list of ids.
*/
public class IdListRequestPayloadGenerator extends BaseRequestGenerator {

protected static final String PAYLOAD_NAME = "id_list";

/**
* Gets the sorted list of required constructor parameters including the request payload
*/
@Override
public ImmutableList<ConstructorParam> toRequiredConstructorParams(final Ds3Request ds3Request) {
final ImmutableList.Builder<Arguments> builder = ImmutableList.builder();
builder.addAll(getNonVoidArgsFromParamList(ds3Request.getRequiredQueryParams()));
builder.addAll(getAssignmentArguments(ds3Request));
builder.add(new Arguments("string", PAYLOAD_NAME));

return builder.build().stream()
.sorted(new CustomArgumentComparator())
.map(arg -> new ConstructorParam(camelToUnderscore(arg.getName()), false))
.collect(GuavaCollectors.immutableList());
}

/**
* Gets the python code that handles processing the request payload and headers
*/
@Override
public String getAdditionalContent(final Ds3Request ds3Request, final String requestName) {
return "if " + PAYLOAD_NAME + " is not None:\n" +
pythonIndent(3) + "if not (isinstance(cur_id, basestring) for cur_id in " + PAYLOAD_NAME + "):\n" +
pythonIndent(4) + "raise TypeError(\n" +
pythonIndent(5) + "'" + requestName + " should have request payload of type: list of strings')\n" +
pythonIndent(3) + "xml_id_list = IdsList(" + PAYLOAD_NAME + ")\n" +
pythonIndent(3) + "self.body = xmldom.tostring(xml_id_list.to_xml())\n";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request
import com.spectralogic.ds3autogen.api.models.apispec.Ds3Type
import com.spectralogic.ds3autogen.api.models.docspec.Ds3DocSpec
import com.spectralogic.ds3autogen.python.generators.request.BaseRequestGenerator
import com.spectralogic.ds3autogen.python.generators.request.RequestModelGenerator
import com.spectralogic.ds3autogen.python.model.request.BaseRequest
import freemarker.template.Configuration
import freemarker.template.Template
Expand All @@ -40,6 +39,8 @@ interface PythonCodeGeneratorInterface {

fun getPutObjectRequestGenerator() : BaseRequestGenerator

fun getIdsRequestGenerator(): BaseRequestGenerator

fun getRequestGenerator(ds3Request: Ds3Request) : BaseRequestGenerator

fun toRequestModel(ds3Request: Ds3Request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ from ds3network import *
<#include "static_classes.ftl" />


class IdsList(object):
def __init__(self, id_list):
for cur_id in id_list:
if not isinstance(cur_id, basestring):
raise TypeError("Ids should only contain strings")
self.id_list = id_list

def to_xml(self):
xml_id_list = xmldom.Element('Ids')
for cur_id in self.id_list:
xml_cur_id = xmldom.Element('Id')
xml_cur_id.text = cur_id
xml_id_list.append(xml_cur_id)
return xml_id_list


# Type Descriptors


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ public void getRequestGenerator_Test() {
assertThat(generator.getRequestGenerator(getGetBlobPersistence()), instanceOf(StringPayloadGenerator.class));
assertThat(generator.getRequestGenerator(getReplicatePutJob()), instanceOf(StringPayloadGenerator.class));

assertThat(generator.getRequestGenerator(clearSuspectBlobAzureTargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(clearSuspectBlobDs3TargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(clearSuspectBlobPoolsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(clearSuspectBlobS3TargetsRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(clearSuspectBlobTapesRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(markSuspectBlobAzureTargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(markSuspectBlobDs3TargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(markSuspectBlobPoolsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(markSuspectBlobS3TargetsAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));
assertThat(generator.getRequestGenerator(markSuspectBlobTapesAsDegradedRequest()), instanceOf(IdListRequestPayloadGenerator.class));

assertThat(generator.getRequestGenerator(getRequestBulkGet()), instanceOf(ObjectsPayloadGenerator.class));
assertThat(generator.getRequestGenerator(getRequestBulkPut()), instanceOf(ObjectsPayloadGenerator.class));
assertThat(generator.getRequestGenerator(getRequestVerifyPhysicalPlacement()), instanceOf(ObjectsPayloadGenerator.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,31 @@ public void headObjectRequest() throws TemplateModelException, IOException {
//Test Client
hasClient(ImmutableList.of(requestName), ds3Code);
}

@Test
public void clearSuspectBlobAzureTargetsRequest() throws IOException, TemplateModelException {
final String requestName = "ClearSuspectBlobAzureTargetsSpectraS3Request";
final FileUtils fileUtils = mock(FileUtils.class);
final TestPythonGeneratedCode codeGenerator = new TestPythonGeneratedCode(fileUtils);

codeGenerator.generateCode(fileUtils, "/input/requests/clearSuspectBlobAzureTargets.xml");
final String ds3Code = codeGenerator.getDs3Code();

CODE_LOGGER.logFile(ds3Code, FileTypeToLog.REQUEST);

final ImmutableList<String> optArgs = ImmutableList.of("force");
final String requestPayload = "id_list";

hasRequestHandler(requestName, HttpVerb.DELETE, ImmutableList.of(), optArgs, ImmutableList.of(), requestPayload, ds3Code);

assertTrue(ds3Code.contains("if id_list is not None:\n" +
" if not (isinstance(cur_id, basestring) for cur_id in id_list):\n" +
" raise TypeError(\n" +
" 'ClearSuspectBlobAzureTargetsSpectraS3Request should have request payload of type: list of strings')\n" +
" xml_id_list = IdsList(id_list)\n" +
" self.body = xmldom.tostring(xml_id_list.to_xml())"));

//Test Client
hasClient(ImmutableList.of(requestName), ds3Code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* ******************************************************************************
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file.
* This file 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.spectralogic.ds3autogen.python.generators.request;

import com.google.common.collect.ImmutableList;
import com.spectralogic.ds3autogen.python.model.request.ConstructorParam;
import com.spectralogic.ds3autogen.utils.collections.GuavaCollectors;
import org.junit.Test;

import static com.spectralogic.ds3autogen.testutil.Ds3ModelFixtures.clearSuspectBlobAzureTargetsRequest;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class IdListRequestPayloadGenerator_Test {

private static final IdListRequestPayloadGenerator generator = new IdListRequestPayloadGenerator();

@Test
public void getAdditionalContentTest() {
final String expected = "if id_list is not None:\n" +
" if not (isinstance(cur_id, basestring) for cur_id in id_list):\n" +
" raise TypeError(\n" +
" 'ClearSuspectBlobAzureTargetsSpectraS3Request should have request payload of type: list of strings')\n" +
" xml_id_list = IdsList(id_list)\n" +
" self.body = xmldom.tostring(xml_id_list.to_xml())\n";
final String result = generator.getAdditionalContent(clearSuspectBlobAzureTargetsRequest(), "ClearSuspectBlobAzureTargetsSpectraS3Request");
assertThat(result, is(expected));
}

@Test
public void toRequiredConstructorParamsTest() {
final ImmutableList<ConstructorParam> reqParams = generator
.toRequiredConstructorParams(clearSuspectBlobAzureTargetsRequest());

final ImmutableList<String> result = reqParams.stream()
.map(ConstructorParam::toPythonCode)
.collect(GuavaCollectors.immutableList());

assertThat(result.size(), is(1));
assertThat(result, hasItem("id_list"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Data>
<Contract>
<RequestHandlers>
<RequestHandler Classification="spectrads3" Name="com.spectralogic.s3.server.handler.reqhandler.spectrads3.degradation.ClearSuspectBlobAzureTargetsRequestHandler">
<Request Action="BULK_DELETE" HttpVerb="DELETE" IncludeIdInPath="false" Resource="SUSPECT_BLOB_AZURE_TARGET" ResourceType="NON_SINGLETON">
<OptionalQueryParams>
<Param Name="Force" Type="void"/>
</OptionalQueryParams>
<RequiredQueryParams/>
</Request>
<ResponseCodes>
<ResponseCode>
<Code>204</Code>
<ResponseTypes>
<ResponseType Type="null"/>
</ResponseTypes>
</ResponseCode>
<ResponseCode>
<Code>400</Code>
<ResponseTypes>
<ResponseType Type="com.spectralogic.s3.server.domain.HttpErrorResultApiBean"/>
</ResponseTypes>
</ResponseCode>
<ResponseCode>
<Code>409</Code>
<ResponseTypes>
<ResponseType Type="com.spectralogic.s3.server.domain.HttpErrorResultApiBean"/>
</ResponseTypes>
</ResponseCode>
</ResponseCodes>
<Version>1.F51C99474F629A2CFD5CDB6BC5CB7C6D</Version>
</RequestHandler>
</RequestHandlers>
</Contract>
</Data>
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ package com.spectralogic.ds3autogen.python3

import com.spectralogic.ds3autogen.python.PythonCodeGenerator
import com.spectralogic.ds3autogen.python.generators.request.BaseRequestGenerator
import com.spectralogic.ds3autogen.python3.generators.request.P3IdListRequestGenerator
import com.spectralogic.ds3autogen.python3.generators.request.P3PutObjectRequestGenerator
import freemarker.template.Configuration
import freemarker.template.Template

class Python3CodeGenerator() : PythonCodeGenerator() {
class Python3CodeGenerator : PythonCodeGenerator() {

/**
* Retrieves the base command template used to generate the Python 3 ds3.py
Expand All @@ -36,4 +37,11 @@ class Python3CodeGenerator() : PythonCodeGenerator() {
override fun getPutObjectRequestGenerator() : BaseRequestGenerator {
return P3PutObjectRequestGenerator()
}

/**
* Retrieves the generator for the Python 3 clear blob and mark blob commands
*/
override fun getIdsRequestGenerator(): BaseRequestGenerator {
return P3IdListRequestGenerator()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* ******************************************************************************
* Copyright 2014-2018 Spectra Logic Corporation. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file.
* This file 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.spectralogic.ds3autogen.python3.generators.request

import com.spectralogic.ds3autogen.api.models.apispec.Ds3Request
import com.spectralogic.ds3autogen.python.generators.request.IdListRequestPayloadGenerator
import com.spectralogic.ds3autogen.python.helpers.PythonHelper.pythonIndent

/**
* Creates the Python 3 request model for the clear blob and mark blob commands
*/
class P3IdListRequestGenerator : IdListRequestPayloadGenerator() {

/**
* Gets the Python 3 code that handles processing the request payload and headers
*/
override fun getAdditionalContent(ds3Request: Ds3Request, requestName : String) : String {
return "if $PAYLOAD_NAME is not None:\n" +
pythonIndent(3) + "if not (isinstance(cur_id, str) for cur_id in $PAYLOAD_NAME):\n" +
pythonIndent(4) + "raise TypeError(\n" +
pythonIndent(5) + "'" + requestName + " should have request payload of type: list of strings')\n" +
pythonIndent(3) + "xml_id_list = IdsList($PAYLOAD_NAME)\n" +
pythonIndent(3) + "self.body = xmldom.tostring(xml_id_list.to_xml())\n"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ from .ds3network import *
<#include "../../python/commands/static_classes.ftl" />


class IdsList(object):
def __init__(self, id_list):
for cur_id in id_list:
if not isinstance(cur_id, str):
raise TypeError("Ids should only contain strings")
self.id_list = id_list

def to_xml(self):
xml_id_list = xmldom.Element('Ids')
for cur_id in self.id_list:
xml_cur_id = xmldom.Element('Id')
xml_cur_id.text = cur_id
xml_id_list.append(xml_cur_id)
return xml_id_list


# Type Descriptors


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;

public class Python3FunctionalTests {
Expand Down Expand Up @@ -87,4 +85,22 @@ public void putObjectRequestTest() throws IOException, TemplateModelException {
assertTrue(ds3Code.contains("for key, val in headers.items():"));
assertFalse(ds3Code.contains("for key, val in headers.iteritems():"));
}

@Test
public void clearSuspectBlobAzureTargetsRequest() throws IOException, TemplateModelException {
final FileUtils fileUtils = mock(FileUtils.class);
final TestPython3GeneratedCode codeGenerator = new TestPython3GeneratedCode(fileUtils);

codeGenerator.generateCode(fileUtils, "/input/requests/clearSuspectBlobAzureTargets.xml");
final String ds3Code = codeGenerator.getDs3Code();

CODE_LOGGER.logFile(ds3Code, FileTypeToLog.REQUEST);

assertTrue(ds3Code.contains("if id_list is not None:\n" +
" if not (isinstance(cur_id, str) for cur_id in id_list):\n" +
" raise TypeError(\n" +
" 'ClearSuspectBlobAzureTargetsSpectraS3Request should have request payload of type: list of strings')\n" +
" xml_id_list = IdsList(id_list)\n" +
" self.body = xmldom.tostring(xml_id_list.to_xml())"));
}
}
Loading

0 comments on commit 23ce9c7

Please sign in to comment.