Swagger UI doesn't support uploading a file properly for RestEasy - jax-rs

I use a JAX-RS (RestEasy) along with a Swagger. One of my endpoint can upload a file. Defined way to upload the file (in RestEasy) is to provide a org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput as a parameter.
Here is my endpoint:
#PUT
#Path("/apis/{id}/file")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(value = "Registers a file.", code = 201, nickname = "registerFile")
#ApiResponses(
value = {
#ApiResponse(code = 201, message = "File created.",
response = FileCreated.class),
#ApiResponse(code = 400, message = "Invalid parameters."),
#ApiResponse(code = 404, message = "API is not found.")})
Response registerFile(
#ApiParam(value = "API ID.", required = true) #PathParam("id") String apiId,
#ApiParam(value = "File to register.", required = true, type = "file", name = "apiFile")
MultipartFormDataInput apiFile) throws AppException;
What is the problem?
Unfortunately, swagger-ui generates a schema based on the inner properties of the MultipartFormDataInput instead of a button to upload the file.
I tried use a #FormParam annotation (to indicate that the providing parameter should be interpreted as file) along with the MultipartFormDataInput parameter, but then the app doesn't want to compile.
Question: Is there any solution/workaround to provide the button to upload the file in the swagger-ui?

The solution is removing #ApiParam from your apiFile argument and adding #ApiImplicitParam (which is not bound to Jax-RS and allows defining parameters manually) above the method :
#ApiImplicitParams({#ApiImplicitParam (value = "File to register.", required = true, dataType = "file", name = "apiFile", paramType="formData")})

The final solution
The final solution includes a selected answer, but instead of removing #ApiParam we should add #ApiParam(hidden = true). Why?
If we remove #ApiParam, there are two fields: apiId, body with the inner properties of the MultipartFormDataInput and the button to upload the file in the swagger-ui. This body field is a side effect. To fix this issue we should provide #ApiParam(hidden = true), then there are the field with apiId and the button to upload the file in the swagger-ui.
BTW: I tested below code for swagger-ui in 1.5.12 version.
#PUT
#Path("/apis/{id}/file")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(value = "Registers a file.", code = 201, nickname = "registerFile")
#ApiResponses(
value = {
#ApiResponse(code = 201, message = "File created.",
response = FileCreated.class),
#ApiResponse(code = 400, message = "Invalid parameters."),
#ApiResponse(code = 404, message = "API is not found.")})
#ApiImplicitParams(
#ApiImplicitParam(value = "File to register.", required = true, dataType = "file",
name = "apiFile", paramType = "formData"))
Response registerFile(
#ApiParam(value = "API ID.", required = true) #PathParam("id") String apiId,
#ApiParam(hidden = true) MultipartFormDataInput apiFile) throws AppException;

Related

What scope is needed to use the findReplace function in GoogleSheets API v4?

I want to use the findReplace request in the Google Sheets APIv4. I set up my Scope and request as defined in the Google quickstart guide for the Sheets API in Python and have confirmed that the API can talk to my spreadsheet.
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#FindReplaceRequest
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
SHEET_ID = myspreadsheetid
creds = None
store = file.Storage('sheets_token.json')
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = client.flow_from_clientsecrets('client_2_https.json', SCOPES)
creds = tools.run_flow(flow, store, http=Http(disable_ssl_certificate_validation=True))
with open('sheets_token.pickle', 'wb') as token:
pickle.dump(creds, token)
adminService = build('sheets', 'v4', http=creds.authorize(Http(disable_ssl_certificate_validation=True)))
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
findreplace_request['sheetId'] = mysheetid
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
body = {}
body.setdefault('requests',[]).append(findreplace_request('#mydate#','TODAY'))
response = adminService.spreadsheets().batchUpdate(spreadsheetId=SHEET_ID, body=my_request).execute()
I clearly set a scope to read and write to/from Google Sheets, but I do not understand why I get an error that says the scope is not set.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\wnh659\AppData\Local\Continuum\anaconda3\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\wnh659\AppData\Local\Continuum\anaconda3\lib\site-packages\googleapiclient\http.py", line 851, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1Sx0CJJo-b6Z6JUaQEQ6cJ3Yxtjv3z9BtHN9EHl0-0jU:batchUpdate?alt=json return
ed "Invalid requests[0].findReplace: scope not set.">
You want to use the findReplace request of Sheets API using python.
You have already been able to modify Spreadsheet using Sheets API.
If my understanding is correct, how about this modification? I think that the reason of the error of Invalid requests[0].findReplace: scope not set. is that the scope for replacing the value is not defined. In your request body, the properties of range, sheetId and allSheets are not used. So how about the following modification?
Modified script:
From:
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
sheetId = mysheetid
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
To:
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
findreplace_request['sheetId'] = mysheetid # Added
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
In this modification, find is searched from the sheet of mysheetid. If you want to search the value from all sheets, please use the property of allSheets instead of sheetId.
Note:
If the value of property is boolean, when the property is not used, the value is used as False of the default value.
In your script, I think that the following modification can be also worked.
body = {}
body.setdefault('requests',[]).append(findreplace_request('#mydate#','TODAY'))
response = adminService.spreadsheets().batchUpdate(spreadsheetId=SHEET_ID, body=body).execute()
Reference:
FindReplaceRequest
If I misunderstood your question and this was not the result you want, I apologize.

How to get request body in angular from ActivatedRoute

As i can get the query params by using ActivatedRoute which is get request. but how can i get request body by using ActivatedRoute from post request. If ActivatedRoute is not right option to get then how should i get request body
This is my jsp code:-
var res = "url which i am creating";
var url =res[0];
var mapForm = document.createElement("form");
mapForm.target = "Test";
mapForm.method = "post";
mapForm.action = url;
//Splitting parameters from url to add into body
var res1 =res[1].split("=");
var name = res1[0];
var value = res1[1];
mapInput3 = document.createElement("input");
mapInput3.type = "hidden";
mapInput3.name =name;
mapInput3.value = value;
mapForm.appendChild(mapInput3);
document.body.appendChild(mapForm);
map = window.open("", "Test", "menubar,
toolbar, location, directories, status, scrollbars,
resizable, dependent, width=1200, height=600,
left=0,top=0");
if (map) {
mapForm.submit();
}
this is my angular code:-
this.activeRoute.queryParams.subscribe(params => {
this.authKey = params['auth_key'];
});
Now if I sent parameter through get method from jsp, I am able to get it from above angular code.
but if i sent params through post method then i get message as " Cannot post"
If I got you right you want to get the body of the query.
You can use snapshot.get and when declare a it with a value something like this ->
const t = this.route.snapshot.mapedQuery.get()
The value of- t is your query body.
Answered from my phone so I can’t format the code

Discord .NET Value of type EmbedBuilder cannot be converted to Embed

As the title says i get "Value of type EmbedBuilder cannot be converted to Embed" error.
This is the code i'm trying right now :
If msg.Equals("gDurum") Then
Dim eb As New EmbedBuilder With {
.Title = "Sunucu Bilgisi",
.Color = New Color(255, 0, 0),
.ImageUrl = "https://cache.gametracker.com/server_info/185.198.73.27:27015/b_560_95_1.png",
.Description = "Deneme"
}
eb.Build()
Await message.Channel.SendMessageAsync("", False, eb)
OK. I found the solution. I was trying to pass the EmbedBuilder instead of Embed.
Here's my new code :
If msg.Equals("gDurum") Then
Dim eb As New EmbedBuilder With {
.Title = "Sunucu Bilgisi",
.Color = New Color(255, 0, 0),
.ImageUrl = "https://cache.gametracker.com/server_info/185.198.73.27:27015/b_560_95_1.png",
.Description = "Deneme"
}
Await message.Channel.SendMessageAsync("", False, eb.Build())
For those who are looking at the official code example might encounter type mismatch while compiling.
Make sure to build Discord.Embed into a Rich Embed which is ready to be sent.
Corrected & working code example for this:
[Command("embed")]
public async Task SendRichEmbedAsync()
{
var embed = new EmbedBuilder
{
// Embed property can be set within object initializer
Title = "Hello world!"
Description = "I am a description set by initializer."
};
// Or with methods
embed.AddField("Field title",
"Field value. I also support [hyperlink markdown](https://example.com)!")
.WithAuthor(Context.Client.CurrentUser)
.WithFooter(footer => footer.Text = "I am a footer.")
.WithColor(Color.Blue)
.WithTitle("I overwrote \"Hello world!\"")
.WithDescription("I am a description.")
.WithUrl("https://example.com")
.WithCurrentTimestamp();
await ReplyAsync(embed: embed.Build());
}

How does ibm - mobile first get mobile number from security context?

I am following "isRegistered" api from this sample code. I did not understand how we get phone number from security context.
The API that I want to use is:
#Path("/isRegistered")
#GET
#Produces("application/json")
#OAuthSecurity(enabled = true)
#ApiOperation(value = "Check if a phone number is registered",
notes = "Check if a phone number is registered",
httpMethod = "GET",
response = Boolean.class
)
#ApiResponses(value = {
#ApiResponse(code = 200, message = "OK",
response = String.class),
#ApiResponse(code = 401, message = "Not Authorized",
response = String.class),
#ApiResponse(code = 500, message = "Cannot check if phone number is registered",
response = String.class)
})
public Boolean isRegistered() {
//Getting client data from the security context
ClientData clientData = securityContext.getClientRegistrationData();
if (clientData == null) {
throw new InternalServerErrorException("This check allowed only from a mobile device.");
}
String number = clientData.getProtectedAttributes().get(SMSOTPSecurityCheck.PHONE_NUMBER);
return number != null && !number.trim().equals("");
}
How does the security context have the client phone number?
There is a client project as well in this sample. Please refer to the complete sample.
Within the client side logic here, the user is asked to provide the phone number , which is sent to the server in an adapter call:
MainViewController.codeDialog("Phone Number", message: "Please provide your phone number",isCode: true) { (phone, ok) -> Void in
if ok {
let resourseRequest = WLResourceRequest(URL: NSURL(string:"/adapters/smsOtp/phone/register/\(phone)")!, method:"POST")
.....
Now in the adapter code path #Path("/register/{phoneNumber}") notice the following code:
clientData.getProtectedAttributes().put(SMSOTPSecurityCheck.PHONE_NUMBER, phoneNumber);
securityContext.storeClientRegistrationData(clientData);
This is how the phone number made it to the security context.
Run the sample and use a tool such as Wireshark to analyze the data flow between client and server.

Adobe Echo Sign Sending PDF file

I am working on Adobe Echo sign,I have downloaded the sample code from their website, I am using this sample code for sendingdocument, it has some code missing in sendDocument method so I have changed it. It's giving SoapHeader Exception,with nothing in InnerException,
{"apiActionId=XHZI4WF4BV693YS"}
below is my code of sending document
public static void sendDocument(string apiKey, string fileName, string recipient)
{
ES = new EchoSignDocumentService16();
FileStream file = File.OpenRead(fileName);
secure.echosign.com.FileInfo[] fileInfos = new secure.echosign.com.FileInfo[1];
fileInfos[0] = new secure.echosign.com.FileInfo(fileName, null, file);
SenderInfo senderInfo = null;
string[] recipients = new string[1];
recipients[0] = recipient;
DocumentCreationInfo documentInfo = new DocumentCreationInfo(
recipients,
"Test from SOAP: " + fileName,
"This is neat.",
fileInfos,
SignatureType.ESIGN,
SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
);
DocumentKey[] documentKeys;
senderInfo = new SenderInfo(recipient, "password", "APIKEY");
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Console.WriteLine("Document key is: " + documentKeys[0].documentKey);
}
its giving exception on this line
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Can anyone suggest some sample code of Adobe Echo Sign?
On the account page of your login there is an API log you can check. If you check the log entry for your request you may find more information there.
I can't see anything immediately wrong with your code however the EchoSign API guide says that the 'tos' field is deprecated and that the recipients field should be used instead. Helpfully this means you can't use the paramaterised constructor. Try creating your document creation info as such (this is C# but if you need Java it should be straightforward to figure out):
RecipientInfo[] recipientInfo = new RecipientInfo[1];
recipientInfo[0] = new RecipientInfo
{
email = "recipient",
role = RecipientRole.SIGNER,
roleSpecified = true
};
DocumentCreationInfo documentCreationInfo = new DocumentCreationInfo
{
recipients = recipientInfo,
name = "Test from SOAP: " + fileName,
message = "This is neat.",
fileInfos = fileInfos,
signatureType = SignatureType.ESIGN,
signatureFlow = SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
};
Note that when using the recipientInfo array it seems that the roleSpecified field must be set to true. This little field tripped me up for ages and I was receiving errors similar to yours.