Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

special paging scenarios #236

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions legacy/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var formData = require('./routes/formData');
var lros = require('./routes/lros');
var lroParameterizedEndpoints = require('./routes/lroParameterizedEndpoints.js');
var paging = require('./routes/paging');
var pagingSpecial = require('./routes/pagingSpecial');
var modelFlatten = require('./routes/model-flatten');
var azureUrl = require('./routes/azureUrl');
var azureSpecial = require('./routes/azureSpecials');
Expand Down Expand Up @@ -548,6 +549,7 @@ app.use('/model-flatten', new modelFlatten(coverage).router);
app.use('/lro', new lros(azurecoverage).router);
app.use('/lroParameterizedEndpoints', new lroParameterizedEndpoints(azurecoverage).router);
app.use('/paging', new paging(azurecoverage).router);
app.use('/pagingSpecial', new pagingSpecial(optionalCoverage).router)
app.use('/azurespecials', new azureSpecial(azurecoverage).router);
app.use('/report', new report(coverage, azurecoverage, optionalCoverage).router);
app.use('/subscriptions', new azureUrl(azurecoverage).router);
Expand Down
92 changes: 92 additions & 0 deletions legacy/routes/pagingSpecial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
var express = require('express');
var router = express.Router();
var util = require('util');
var utils = require('../util/utils');

var pagingSpecial = function(optionalCoverage) {
optionalCoverage['PagingSpecialNextLinkInResponseHeaders'] = 0;
optionalCoverage['PagingSpecialContinuationToken'] = 0;
optionalCoverage["PagingSpecialContinuationTokenInResponseHeaders"] = 0;
optionalCoverage["PagingSpecialContinuationTokenWithMetadata"] = 0;


router.get('/nextLinkInResponseHeaders', function(req, res, next) {
var headers = {
'x-ms-nextLink': '/pagingSpecial/nextLinkInResponseHeaders/page/2',
};
res.set(headers).status(200).json({ "value" : [ {"properties":{"name": "Product" }}] });
});


router.get('/nextLinkInResponseHeaders/page/:pagenumber', function(req, res, next) {
if (req.params.pagenumber < 10) {
var headers = {
'x-ms-nextLink': '/pagingSpecial/nextLinkInResponseHeaders/page/' + (++req.params.pagenumber),
};
res.set(headers).status(200).json({"value": [ {"properties":{"name": "product"}} ]});
} else {
optionalCoverage['PagingSpecialNextLinkInResponseHeaders']++;
res.status(200).json({"value": [ {"properties":{"name": "product"}} ]});
}
});

router.get('/continuationToken', function(req, res, next) {

if (req.headers["x-ms-token"]) {
contToken = req.headers["x-ms-token"]
if (contToken < 10) {
res.status(200).json({ "value": [ {"properties":{"name": "product"}} ], "token": ++contToken});
} else {
res.status(200).json({"value": [ {"properties":{"name": "product"}} ]});
}

} else {
optionalCoverage['PagingSpecialContinuationToken']++;
res.status(200).json({ "value": [ {"properties":{"name": "product"}} ], "token": 2});
}

});

router.get('/continuationTokenInResponseHeaders', function(req, res, next) {

if (req.headers["x-ms-token"]) {
contToken = req.headers["x-ms-token"]
if (contToken < 10) {
var headers = {
"x-ms-token": ++contToken,
};
res.set(headers).status(200).json({ "value" : [ {"properties":{"name": "Product" }}] });
} else {
optionalCoverage["PagingSpecialContinuationTokenInResponseHeaders"]++;
res.status(200).json({"value": [ {"properties":{"name": "product"}} ]});
}

} else {
var headers = {
"x-ms-token": 2,
};
res.set(headers).status(200).json({ "value" : [ {"properties":{"name": "Product" }}] });
}

});

router.get('/tokenWithMetadata', function(req, res, next) {
if (req.headers["x-ms-token"]) {
contToken = req.headers["x-ms-token"]
if (contToken < 10) {
res.status(200).json({ "value": [ {"properties":{"name": "product"}} ], "token": ++contToken + ";10"});
} else {
optionalCoverage['PagingSpecialContinuationTokenWithMetadata']++;
res.status(200).json({"value": [ {"properties":{"name": "product"}} ]});
}

} else {
res.status(200).json({ "value": [ {"properties":{"name": "product"}} ], "token": "2;10"});
}
});

};

pagingSpecial.prototype.router = router;

module.exports = pagingSpecial;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft.azure/autorest.testserver",
"version": "2.10.65",
"version": "2.10.66",
"main": "./legacy/startup/www.js",
"bin": {
"start-autorest-express": "./.scripts/start-autorest-express.js",
Expand Down
155 changes: 155 additions & 0 deletions swagger/paging-special.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"swagger": "2.0",
"info": {
"title": "AutoRest Special Paging Test Service",
"description": "Long-running Operation for AutoRest",
"version": "1.0.0"
},
"host": "localhost:3000",
"schemes": [
"http"
],
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"paths": {
"/pagingSpecial/nextLinkInResponseHeaders": {
"get": {
"x-ms-pageable": { "nextLinkName": null},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to set nextLinkName to ""x-ms-nextLink" instead of null?

Looking at the docs for x-ms-pageable, and as I understand it, setting nextLinkName to null would mean that there is no next operation to call. However in this scenario there is, and there is also a nextLink, it is just not in the requestBody.

"operationId": "nextLinkInResponseHeaders",
"description": "A paging operation where the next link is found in the response headers, not in the response body",
"responses": {
"200": {
"headers": {
"x-ms-nextLink": {
"description": "Next link for subsequent calls",
"type": "string"
}
},
"description": "Returns a list of products, where the next link for continued paging is located in response header x-ms-nextLink.",
"schema": {
"$ref": "#/definitions/ProductResultValue"
}
},
"default": {
"description": "Unexpected error"
}
}
}
},
"/pagingSpecial/continuationToken": {
"get": {
"x-ms-pageable": { "nextLinkName": "token"},
"operationId": "continuationToken",
"description": "A paging operation where the token in the response body needs to be passed into subsequent calls.",
"responses": {
"200": {
"description": "Returns a list of products",
"schema": {
"$ref": "#/definitions/ProductResultValueWithToken"
}
},
"default": {
"description": "Unexpected error"
}
}
}
},
"/pagingSpecial/continuationTokenInResponseHeaders": {
"get": {
"x-ms-pageable": { "nextLinkName": null},
"operationId": "continuationTokenInResponseHeaders",
"description": "A paging operation where the continuation is found in the response headers, and needs to be passed into subsequent calls.",
"parameters": [
{
"name": "continuationToken",
"in": "header",
"type": "string",
"description": "Continuation token for subsequent paging."
}
],
"responses": {
"200": {
"headers": {
"x-ms-continuationToken": {
"description": "Next link for subsequent calls",
"type": "string"
}
},
"description": "Returns a list of products, where the next link for continued paging is located in response header x-ms-nextLink.",
"schema": {
"$ref": "#/definitions/ProductResultValueWithToken"
}
},
"default": {
"description": "Unexpected error"
}
}
}
},
"/pagingSpecial/tokenWithMetadata": {
"get": {
"x-ms-pageable": { "nextLinkName": "token"},
"operationId": "tokenWithMetadata",
"description": "A paging operation that returns a continuation token, and metadata about the number of total results. Should be able to access metadata from pager.",
"responses": {
"200": {
"description": "Returns a list of products. Should be able to access the metadata from the pager returned by this operation, which is just the number 10 (the number of items)",
"schema": {
"$ref": "#/definitions/ProductResultValueWithToken"
}
},
"default": {
"description": "Unexpected error"
}
}
}
}
},
"definitions": {
"ProductResultValue": {
"type": "object",
"properties": {
"value": {
"type": "array",
"items": {
"$ref": "#/definitions/Product"
}
},
"nextLink": {
"type": "string"
}
}
},
"ProductResultValueWithToken": {
"type": "object",
"properties": {
"value": {
"type": "array",
"items": {
"$ref": "#/definitions/Product"
}
},
"token": {
"type": "string"
}
}
},
"Product": {
"type": "object",
"properties": {
"properties": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
}