Grails injected Mail Service bean is null inside a controller - email

I am trying to use the following Grails Mail plugin: https://grails.org/plugin/mail
I've added the depedency in BuildConfig.groovy:
plugins {
//mail plugin
compile "org.grails.plugins:mail:1.0.7"
}
The I've configured it to use a specific email by adding the following code in Config.groovy:
grails {
mail {
host = "smtp.gmail.com"
port = 465
username = "-my email-"
password = "-my password-"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
from = "no-reply#kunega.com"
}
}
I have a controller where I declare the mailService so it should be injectd as a bean:
#Secured("permitAll")
class RegisterController {
def mailService
def springSecurityService
#Transactional
def registerAccount(UserCommand userCommand) {
def model
if (springSecurityService.isLoggedIn()) {
model = [success: false, message: 'Log out to register a new account.']
response.status = 400
} else if (userCommand.validate()) {
User u = userCommand.createUser()
u.save(flush: true);
Role role = Role.findByAuthority("ROLE_USER")
UserRole.create u, role, true
def link = createLink(controller: 'register', action: 'activateAccount', params: [code: u.confirmCode])
mailService.sendMail {
async true
to 'kunega#mailinator.com'
html "Activate your account on Kunega"
}
model = [success: true, message: 'An activation link has been sent to your email.']
response.status = 201
} else {
model = [success: false, errors: userCommand.getErrors()]
response.status = 400
}
render model as JSON
}
}
I am trying to use the sendMail method it in the registerAccount method of the controller. However I get an error, which basically says that the mailService object is null. Here is the error message:
errors.GrailsExceptionResolver NullPointerException occurred when processing request: [POST] /Kunega/register/createAccount
Cannot invoke method $() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method $() on null object
at com.kunega.RegisterController$_$tt__registerAccount_closure2.doCall(RegisterController.groovy:32)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:53)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:59)
at com.kunega.RegisterController.$tt__registerAccount(RegisterController.groovy:29)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:198)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
And there is another strange thing that I should mention. I'm using IntelliJ Ultimate Edition, and here is a curios thing:
If you notice inside the highlighted area with red, the IDE is showing that it can't recognize the arguments inside the closure that is passed to sendEmail.
I've never used this plugin before, so I just followed the steps in the docs, but apparently something is wrong. Thank you for your help.

In your code you have:
html "Activate your account on Kunega"
which I suppose should be either:
html "Activate your account on Kunega"
or
html "Activate your account on Kunega"
otherwise you call a method html with params "Activate your account on Kunega".

Related

Akka Http route test with formFields causing UnsupportedRequestContentTypeRejection

I have a GET request with parameters and a formField.
It works when I use a client like Insomnia/Postman to send the req.
But the route test below fails with the error:
UnsupportedRequestContentTypeRejection(Set(application/x-www-form-urlencoded, multipart/form-data))
(Rejection created by unmarshallers. Signals that the request was rejected because the requests content-type is unsupported.)
I have tried everything I can think of to fix it but it still returns the same error.
It is the formField that causes the problem, for some reason when called by the test it doesnt like the headers.
Is it something to do with withEntity ?
Code:
path("myurl" ) {
get {
extractRequest { request =>
parameters('var1.as[String], 'var2.as[String], 'var3.as[String], 'var4.as[String]) { (var1, var2, var3, var4) =>
formField('sessionid.as[String]) { (sessionid) =>
complete {
request.headers.foreach(a => println("h=" + a))
}
}
}
}
}
}
Test:
// TESTED WITH THIS - Fails with UnsupportedRequestContentTypeRejection(Set(application/x-www-form-urlencoded, multipart/form-data))
class GETTest extends FreeSpec with Matchers with ScalatestRouteTest {
val get = HttpRequest(HttpMethods.GET, uri = "/myurl?var1=456&var2=123&var3=789&var4=987")
.withEntity("sessionid:1234567890")
.withHeaders(
scala.collection.immutable.Seq(
RawHeader("Content-Type", "application/x-www-form-urlencoded"), // same problem if I comment out these 2 Content-Type lines
RawHeader("Content-Type", "multipart/form-data"),
RawHeader("Accept", "Application/JSON")
)
)
get ~> route ~> check {
status should equal(StatusCodes.OK)
}
The exception is thrown before the formField line.
Full exception:
ScalaTestFailureLocation: akka.http.scaladsl.testkit.RouteTest$$anonfun$check$1 at (RouteTest.scala:57)
org.scalatest.exceptions.TestFailedException: Request was rejected with rejection UnsupportedRequestContentTypeRejection(Set(application/x-www-form-urlencoded, multipart/form-data))
at akka.http.scaladsl.testkit.TestFrameworkInterface$Scalatest$class.failTest(TestFrameworkInterface.scala:24)
}
You could either use:
val get = HttpRequest(HttpMethods.GET, uri = "/myurl?var1=456&var2=123&var3=789&var4=987", entity = FormData("sessionid" -> "1234567.890").toEntity)
or
val get = Get("/myurl?var1=456&var2=123&var3=789&var4=987", FormData("sessionid" -> "1234567.890"))

RESTful client in Unity - validation error

I have a RESTful server created with ASP.Net and am trying to connect to it with the use of a RESTful client from Unity. GET works perfectly, however I am getting a validation error when sending a POST request. At the same time both GET and POST work when sending requests from Postman.
My Server:
[HttpPost]
public IActionResult Create(User user){
Console.WriteLine("***POST***");
Console.WriteLine(user.Id+", "+user.sex+", "+user.age);
if(!ModelState.IsValid)
return BadRequest(ModelState);
_context.Users.Add(user);
_context.SaveChanges();
return CreatedAtRoute("GetUser", new { id = user.Id }, user);
}
My client:
IEnumerator PostRequest(string uri, User user){
string u = JsonUtility.ToJson(user);
Debug.Log(u);
using (UnityWebRequest webRequest = UnityWebRequest.Post(uri, u)){
webRequest.SetRequestHeader("Content-Type","application/json");
yield return webRequest.SendWebRequest();
string[] pages = uri.Split('/');
int page = pages.Length - 1;
if (webRequest.isNetworkError || webRequest.isHttpError){
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
}
else{
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
}
}
}
I was trying both with the Json conversion and writing the string on my own, also with the WWWForm, but the error stays.
The error says that it's an unknown HTTP error. When printing the returned text it says:
"One or more validation errors occurred.","status":400,"traceId":"|b95d39b7-4b773429a8f72b3c.","errors":{"$":["'%' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0."]}}
On the server side it recognizes the correct method and controller, however, it doesn't even get to the first line of the method (Console.WriteLine). Then it says: "Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ValidationProblemDetails'".
Here're all of the server side messages:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5001/user application/json 53
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect)'
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Route matched with {action = "Create", controller = "User"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult Create(TheNewestDbConnect.Data.Entities.User) on controller TheNewestDbConnect.Controllers.UserController (TheNewestDbConnect).
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ValidationProblemDetails'.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
Executed action TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect) in 6.680400000000001ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect)'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 11.3971ms 400 application/problem+json; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
I have no idea what is happening and how to solve it. Any help will be strongly appreciated!
Turned out I was just missing an upload handler. Adding this line solved it: webRequest.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(JsonObject));

Why do I get an MSPL exception "ProxyRequest only valid for sipRequest"

I'm writing a Lync MSPL application using a manifest and a windows service. In my manifest.am I have the following code:
<?xml version="1.0"?>
<r:applicationManifest
r:appUri="http://www.company.no/LyncServerFilter"
xmlns:r="http://schemas.microsoft.com/lcs/2006/05">
<r:requestFilter methodNames="ALL"
strictRoute="true"
domainSupported="false"/>
<r:responseFilter reasonCodes="ALL"/>
<r:proxyByDefault action="true" />
<r:allowRegistrationBeforeUserServices action="true" />
<r:splScript>
<![CDATA[
callId = GetHeaderValues("Call-ID");
cseq = GetHeaderValues("CSeq");
content = "";
sstate = GetHeaderValues("subscription-state");
xevent = GetHeaderValues("Event");
xdir = GetHeaderValues("Direction");
xexp = GetHeaderValues("Session-Expires");
referto = GetHeaderValues("Refer-To");
if (sipRequest)
{
if (sipRequest.Method == "INVITE") {
if (ContainsString(sipRequest.Content, "m=audio", true)) {
content = "audio";
}
else if (ContainsString(sipRequest.Content, "m=video", true)) {
content = "video";
}
else if (ContainsString(sipRequest.Content, "m=message", true)) {
content = "message";
}
else if (ContainsString(sipRequest.Content, "m=application", true)) {
content = "application";
}
else {
content = "unknown";
}
}
else if (sipRequest.Method == "NOTIFY" || sipRequest.Method == "BENOTIFY") {
content = sipRequest.Content;
}
DispatchNotification("OnRequest", sipRequest.Method, sipMessage.From, sipMessage.To, callId, cseq, content, xdir, xevent, sstate, xexp, referto);
if (sipRequest) {
ProxyRequest();
}
}
else if(sipResponse) {
DispatchNotification("OnResponse", sipResponse.StatusCode, sipResponse.StatusReasonPhrase, sipMessage.From, sipMessage.To, callId, cseq, content, xdir, xevent, sstate, xexp, referto);
ProxyResponse();
}
]]></r:splScript>
</r:applicationManifest>
I'm getting the following errormessage in Eventlog on Lync Front End server:
Lync Server application MSPL script execution aborted because of an error
Application Uri at 'http://www.company.no/LyncServerFilter', at line 60
Error: 0x80070057 - The parameter is incorrect
Additional information: ProxyRequest only valid for sipRequest
Line 60 is where I call ProxyRequest:
if (sipRequest) {
ProxyRequest();
}
Questions:
Why does the errormessage say that ProxyRequest is only valid for a sipRequest? I'm checking that it is a sipMessage right?
Can I remove my call to ProxyRequest() since I have set proxyByDefault=true? Does the DistpathNotification-method "handle" the method (swallow it), or will the message be proxied by default? The code "works" when I remove the call to ProxyRequest(), but I'm not sure what the consequences are...
The ProxyRequest method takes a argument of the uri, which is why you are getting the compile error message.
So you should be calling it like:
ProxyRequest(""); // send to the URI specified in the request itself
Removing it effectivity does the same thing as per your proxyByDefault setting being set to true:
If true, the server automatically proxies any messages that are not handled by the application. If false, the message is dropped and applications that follow this application in the application execution order will not receive it. The default value is true.
As a side-note, you can use compilespl.exe, which comes as part of the Lync Server SDK to verify that your MSPL script is correct before trying to start it on the lync server.
Check out this link in the 'Compile the MSPL application separately' section.

How to test remote (production) Scalatra web service with Specs2?

I'm using Specs2 to test my Scalatra web service.
class APISpec extends ScalatraSpec {
def is = "Simple test" ^
"invalid key should return status 401" ! root401^
addServlet(new APIServlet(),"/*")
def root401 = get("/payments") {
status must_== 401
}
}
This tests the web service locally (localhost). Now I would like to perform the same tests to the production Jetty server. Ideally, I would be able to do this by only changing some URL. Is this possible at all ? Or do I have to write my own (possible duplicate) testing code for the production server?
I don't know how Scalatra manages its URLs but one thing you can do in specs2 is control parameters from the command-line:
class APISpec extends ScalatraSpec with CommandLineArguments { def is = s2"""
Simple test
invalid key should return status 401 $root401
${addServlet(new APIServlet(),s"$baseUrl/*")}
"""
def baseUrl = {
// assuming that you passed 'url www.production.com' on the command line
val args = arguments.commandLine.split(" ")
args.zip(args.drop(1)).find { case (name, value) if name == "url" => value }.
getOrElse("localhost:8080")
}
def root401 = get(s"$baseUrl/payments") {
status must_== 401
}
}

Scalate ResourceNotFoundException in Scalatra

I'm trying the following based on scalatra-sbt.g8:
class FooWeb extends ScalatraServlet with ScalateSupport {
beforeAll { contentType = "text/html" }
get("/") {
templateEngine.layout("/WEB-INF/scalate/templates/hello-scalate.jade")
}
}
but I'm getting the following exception (even though the file exists) - any clues?
Could not load resource: [/WEB-INF/scalate/templates/hello-scalate.jade]; are you sure it's within [null]?
org.fusesource.scalate.util.ResourceNotFoundException: Could not load resource: [/WEB-INF/scalate/templates/hello-scalate.jade]; are you sure it's within [null]?
FWIW, the innermost exception is coming from org.mortbay.jetty.handler.ContextHandler.getResource line 1142: _baseResource==null.
Got an answer from the scalatra mailing list. The problem was that I was starting the Jetty server with:
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.{Context,ServletHolder}
val server = new Server(8080)
val root = new Context(server, "/", Context.SESSIONS)
root.addServlet(new ServletHolder(new FooWeb()), "/*")
server.start()
I needed to insert this before start():
root.setResourceBase("src/main/webapp")