X-CGP-ClamAV-Result: CLEAN X-VirusScanner: Niversoft's CGPClamav Helper v1.22.2a (ClamAV engine v0.102.2) X-Junk-Score: 0 [] X-KAS-Score: 0 [] From: "Don Lindsay" Received: from st43p00im-zteg10063401.me.com ([17.58.63.175] verified) by post.selbstdenker.com (CommuniGate Pro SMTP 6.3.3) with ESMTPS id 25362145 for webobjects-dev@wocommunity.org; Thu, 04 Feb 2021 15:22:01 +0100 Received-SPF: pass receiver=post.selbstdenker.com; client-ip=17.58.63.175; envelope-from=pccdonl@icloud.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1612448499; bh=qRRNLR2tkOX3luLxazpOoa8MmKAw2d93Z7XwktRP9MM=; h=From:Content-Type:Mime-Version:Subject:Date:To:Message-Id; b=L46YKFmiROyMEzjyRRmtHOAoKd+SOa7hYuQFy2hMZbVhnbWH4XpYo+miRdYIF522S AwpbSuWy56ERnffZ7HD55dLG470zl5pWX802Xk9dC1FE+nJ9L+2OS95ePXq2nrI3Tn lxrw0hZwK/LAjWuZfH4pO5SMSwYGGAi7JGOWDHfowIy5hD/9LFcUzXiZmBA92ZpqFE pPlnYKeF2QQl68lAWCOvxIH2+xIyGGknTUJAlsclyRGE7DoSaNSZpwKYpixwqZHgaU LW1MOgrPd5RmAeMALGo3w1A6uukjznRe7VunmDubIM0S7R5dr6GjdOyp0G1lKbgjGJ LF1EdKintSktQ== Received: from [192.168.1.110] (ip-69-10-101-174.midstate.ip.cablemo.net [69.10.101.174]) by st43p00im-zteg10063401.me.com (Postfix) with ESMTPSA id A01E34A0530 for ; Thu, 4 Feb 2021 14:21:38 +0000 (UTC) Content-Type: multipart/alternative; boundary="Apple-Mail=_8740C871-A82C-4A1D-8988-304769CBAD4E" Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.40.0.2.32\)) Subject: Re: [WO-DEV] ERRest PUT not functioning Date: Thu, 4 Feb 2021 08:21:37 -0600 References: To: WebObjects & WOnder Development In-Reply-To: Message-Id: <8B7123D3-9712-469C-8FCC-E6DF5D4749D7@icloud.com> X-Mailer: Apple Mail (2.3654.40.0.2.32) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369,18.0.737 definitions=2021-02-04_07:2021-02-04,2021-02-04 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-2006250000 definitions=main-2102040093 --Apple-Mail=_8740C871-A82C-4A1D-8988-304769CBAD4E Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 They are not part of the code. They can be used but should not be = needed, ERRest should configure the methods (as in the Wonder examples) = and their routes from the code in the Application. ERXRouteRequestHandler restRequestHandler =3D new = ERXRouteRequestHandler(ERXRouteRequestHandler.WO); = restRequestHandler.addDefaultRoutes(TileV2.ENTITY_NAME,TileV2.ENTITY_NAME,= true, TileV2Controller.class); = restRequestHandler.addDefaultRoutes(DashboardV2.ENTITY_NAME,DashboardV2.EN= TITY_NAME,true,DashboardV2Controller.class); = restRequestHandler.addDefaultRoutes(DashboardsTilesV2.ENTITY_NAME,Dashboar= dsTilesV2.ENTITY_NAME,true,DashboardsTilesV2Controller.class); = restRequestHandler.addDefaultRoutes(Databasedetails.ENTITY_NAME,Databasede= tails.ENTITY_NAME,true,DatabasedetailsController.class); restRequestHandler.addDefaultRoutes("Driver"); restRequestHandler.addDefaultRoutes("TileQuery"); ERXRouteRequestHandler.register(restRequestHandler); I have changed to use the annotations at this point because I don=E2=80=99= t have time to debug the Wonder code to find out what I may have done = wrong or if there is a bug. Many things are not working as I expected, and that may be errors on my = part. For instance after I mark a method as a put, or delete verbs, the = json that is part of the body is not used in the create method of the = for the entity when the server receives the http request. But it does = marshal the JSON for the post verb > On Feb 3, 2021, at 10:46, Peer Sandtner = wrote: >=20 > Ok, i know about annotations in general, but I was not aware, that = ERRest supports it. > And especially: These annotations are not part of your example code = (TileV2Controller.java) >=20 > Or do I miss something? >=20 > Peer >=20 >=20 >> Am 03.02.2021 um 16:07 schrieb Don Lindsay = >: >>=20 >> Hello Peer; >>=20 >> There are annotations that can be used to mark methods for specific = http verbs (@GET, @PUT, @POST, etc) it is combined with the @Path = annotation which is passed a value for the path to the method (/TileV2, = /TileV2/Delete, etc). I think it is a way to do route creation without = multiple lines of java code, like you showed. >>=20 >> Thanks >>=20 >> Don >>=20 >>> On Feb 3, 2021, at 07:40, Peer Sandtner = > = wrote: >>>=20 >>> Ah, yes. Sorry, I was blind. >>>=20 >>>> I am in development mode right now. I see the put coming into the = server and I can get it to go to the method using the @PUT annotation = with the @PATH, but the json never gets put into a key so I can=E2=80=99t = get the object to update. >>>=20 >>>=20 >>> "using the @PUT annotation with the @PATH"? What do you mean by = that? Hm, excuse my stupidity... >>>=20 >>> How do you configure your ERXRouteRequestHandler? Something like in = er.rest.example.Application (ERRestRouteExample)? I'm always doing = something like: >>>=20 >>> ERXRouteRequestHandler routeRequestHandler =3D new = ERXRouteRequestHandler(ERXRouteRequestHandler.WO); >>> routeRequestHandler.addRoute(new ERXRoute(Person.ENTITY_NAME, = "/Person/{person:Person}", ERXRoute.Method.Put, PersonController.class, = "update")); >>>=20 >>> regards, >>> Peer >>>=20 >>>=20 >>>=20 >>>> Am 03.02.2021 um 09:40 schrieb Don Lindsay = >: >>>>=20 >>>> Hello; >>>>=20 >>>> I am in development mode right now. I see the put coming into the = server and I can get it to go to the method using the @PUT annotation = with the @PATH, but the json never gets put into a key so I can=E2=80=99t = get the object to update. >>>>=20 >>>> Thanks, >>>>=20 >>>> Don >>>>=20 >>>>> On Feb 3, 2021, at 02:17, Peer Sandtner = > = wrote: >>>>>=20 >>>>> Hello Don, >>>>>=20 >>>>> are you using an Apache? In my case I had to modify = webobjects.conf: >>>>>=20 >>>>> # Specific to Apache 2.4 >>>>> >>>>> >>>>> Require all granted >>>>> >>>>> Require all denied >>>>> =20 >>>>>=20 >>>>> Peer >>>>>=20 >>>>>=20 >>>>>=20 >>>>>> Am 03.02.2021 um 07:21 schrieb Don Lindsay = >: >>>>>>=20 >>>>>> Hello; >>>>>>=20 >>>>>> I have a ERRest project. Everything seems to be working except = for when I update an entity the updateAction never gets called. I put = breakpoints in the source code on createAction, updateAction, = indexAction, showAction. The method that gets called for PUT is = indexAction. Am I doing something wrong with the code, I took a look at = the example apps in Project Wonder and used them to create my = boilerplate. >>>>>> =20 >>>>>> Thanks, >>>>>>=20 >>>>>> Don >>>>>>=20 >>>>>>=20 >>>>>> The request from the developer tools in the browser: >>>>>>=20 >>>>>> >>>>>>=20 >>>>>>=20 >>>>>> How the data is being sent: >>>>>>=20 >>>>>> $.ajax({ >>>>>> url: '/cgi-bin/WebObjects/xxxxxx.woa/ra/TileV2', >>>>>> type: =E2=80=98PUT', >>>>>> data: workingObject, >>>>>> dataType: 'json', >>>>>> contentType: 'application/json', >>>>>> success: function (data) { >>>>>> comp._currentTile =3D data; >>>>>> console.log(JSON.stringify(data)) >>>>>> bootbox.alert({ >>>>>> title: "Tile Save", >>>>>> message: "Tile saved successfully", >>>>>> centerVertical: true >>>>>> }); >>>>>> comp.resetDirty(); >>>>>> comp.initialize(window.connectorsjson, window.tilejson);; >>>>>> }, >>>>>> error: function (data) { >>>>>> bootbox.alert({ >>>>>> title: "Tile Save", >>>>>> message: "Saving the tile failed, please try again = later", >>>>>> centerVertical: true >>>>>> }); >>>>>> } >>>>>> }); >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>> TileV2Controller.java >>>>>>=20 >>>>>> public class TileV2Controller extends BaseRestController { >>>>>>=20 >>>>>> public TileV2Controller(WORequest request) { >>>>>> super(request); >>>>>> // TODO Auto-generated constructor stub >>>>>> } >>>>>>=20 >>>>>> @Override >>>>>> public WOActionResults createAction() throws Throwable { >>>>>> TileV2 tilev2 =3D create(createInFilter()); >>>>>> editingContext().saveChanges(); >>>>>> return response(tilev2,outFilter()); >>>>>> } >>>>>>=20 >>>>>> public ERXKeyFilter createInFilter() { >>>>>> return ERXKeyFilter.filterWithAttributes(); >>>>>> } >>>>>>=20 >>>>>> public ERXKeyFilter outFilter() { >>>>>> ERXKeyFilter out =3D createInFilter(); >>>>>> return out; >>>>>> } >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>> /** >>>>>> * Returns the value of the "tile" variable from the route. >>>>>> * @return >>>>>> */ >>>>>> public TileV2 tilev2() { >>>>>> TileV2 tilev2 =3D routeObjectForKey("tileV2"); >>>>>> = tilev2.setTenant(((com.mozaic.app.Session)session()).getTenant()); >>>>>> return tilev2; >>>>>> } >>>>>>=20 >>>>>> /** >>>>>> * The query filter is used in indexAction to control what = attributes and relationships >>>>>> * you expose to qualifiers through query parameters >>>>>> *=20 >>>>>> * @return >>>>>> */ >>>>>> public static ERXKeyFilter queryFilter() { >>>>>> ERXKeyFilter filter =3D = ERXKeyFilter.filterWithAllRecursive(); >>>>>> filter.includeAll(); >>>>>> return filter; >>>>>> } >>>>>>=20 >>>>>> /** >>>>>> * This showFilter is used by indexAction and showAction and = says to return all attributes >>>>>> * of an TileV2, and for the owner, include all of its = attributes.=20 >>>>>> */ >>>>>> public static ERXKeyFilter showFilter() { >>>>>> ERXKeyFilter filter =3D = ERXKeyFilter.filterWithAttributes(); >>>>>> return filter; >>>>>> } >>>>>>=20 >>>>>> /** >>>>>> * The updateFilter is used by updateAction and createAction and = says to allow updating any attributes of an >>>>>> * TileV2. >>>>>> * @return >>>>>> */ >>>>>> public static ERXKeyFilter updateFilter() { >>>>>> ERXKeyFilter filter =3D = ERXKeyFilter.filterWithAttributes(); >>>>>> return filter; >>>>>> } >>>>>>=20 >>>>>> @Override >>>>>> public WOActionResults updateAction() { >>>>>> TileV2 tilev2 =3D tilev2(); >>>>>> update(tilev2, updateFilter()); >>>>>> editingContext().saveChanges(); >>>>>> return response(tilev2, showFilter()); >>>>>> } >>>>>>=20 >>>>>> @Override >>>>>> public WOActionResults destroyAction() throws Throwable { >>>>>> TileV2 tilev2 =3D tilev2(); >>>>>> tilev2.delete(); >>>>>> editingContext().saveChanges(); >>>>>> return response(tilev2, showFilter()); >>>>>> } >>>>>>=20 >>>>>> @Override >>>>>> public WOActionResults newAction() throws Throwable { >>>>>> TileV2 tilev2 =3D TileV2.createTileV2(editingContext(), = "New Description", null, "New Tile", = ((com.mozaic.app.Session)session()).getTenant()); >>>>>> return response(tilev2, showFilter()); >>>>>> } >>>>>>=20 >>>>>> @Override >>>>>> public WOActionResults showAction() { >>>>>> return response(tilev2(), showFilter()); >>>>>> } >>>>>>=20 >>>>>> /** >>>>>> * indexAction uses an ERXRestFetchSpecification, which = optionally allows you to expose sorting, qualifying, and batching in = query parameters=20 >>>>>> */ >>>>>> @Override >>>>>> public WOActionResults indexAction() { >>>>>> if (isSchemaRequest()) { >>>>>> return schemaResponse(showFilter()); >>>>>> } >>>>>> ERXRestFetchSpecification fetchSpec =3D new = ERXRestFetchSpecification<>(TileV2.ENTITY_NAME, null, null, = queryFilter(), TileV2.NAME.ascs(), 25); >>>>>> return response(fetchSpec, showFilter()); >>>>>> } >>>>>>=20 >>>>>>=20 >>>>>> } >>>>>>=20 >>>>>=20 >>>>=20 >>>=20 >>=20 >=20 --Apple-Mail=_8740C871-A82C-4A1D-8988-304769CBAD4E Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 They = are not part of the code.  They can be used but should not be = needed, ERRest should configure the methods (as in the Wonder examples) = and their routes from the code in the Application.


  =      ERXRouteRequestHandler restRequestHandler =3D new = ERXRouteRequestHandler(ERXRouteRequestHandler.WO);
restRequestHandler.addDefaultRoutes(TileV2.ENTITY_NAME,TileV2.ENTITY_NAME,true, TileV2Controller.class);
= restRequestHandler.addDefaultRoutes(DashboardV2.ENTITY_NAME,DashboardV2.ENTITY_NAME,true,DashboardV2Controller.class);
= restRequestHandler.addDefaultRoutes(DashboardsTilesV2.ENTITY_NAME,DashboardsTilesV2.ENTITY_NAME,true,DashboardsTilesV2Controller.class);
= restRequestHandler.addDefaultRoutes(Databasedetails.ENTITY_NAME,Databasedetails.ENTITY_NAME,true,DatabasedetailsController.class);
= restRequestHandler.addDefaultRoutes("Driver");
restRequestHandler.addDefaultRoutes("TileQuery");
    = ERXRouteRequestHandler.register(restRequestHandler);

I have changed to use = the annotations at this point because I don=E2=80=99t have time to debug = the Wonder code to find out what I may have done wrong or if there is a = bug.

Many = things are not working as I expected, and that may be errors on my part. =  For instance after I mark a method as a put, or delete verbs, the = json that is part of the body is not used in the create method of the = for the entity when the server receives the http request.  But it = does marshal the JSON for the post verb



On Feb = 3, 2021, at 10:46, Peer Sandtner <webobjects-dev@wocommunity.org> wrote:

Ok, i know about = annotations in general, but I was not aware, that ERRest supports = it.
And especially: These annotations are not part of = your example code (TileV2Controller.java)

Or do I miss something?

Peer


Am 03.02.2021 um 16:07 schrieb = Don Lindsay <webobjects-dev@wocommunity.org>:

Hello Peer;

There are annotations = that can be used to mark methods for specific http verbs (@GET, @PUT, = @POST, etc) it is combined with the @Path annotation which is passed a = value for the path to the method (/TileV2, /TileV2/Delete, etc).  I = think it is a way to do route creation without multiple lines of java = code, like you showed.

Thanks

Don

On Feb 3, 2021, at 07:40, Peer = Sandtner <webobjects-dev@wocommunity.org> wrote:

Ah, = yes. Sorry, I was blind.

I am in development mode right now. =  I see the put coming into the server and I can get it to go to the = method using the @PUT annotation with the @PATH, but the json never gets = put into a key so I can=E2=80=99t get the object to = update.

"using the @PUT annotation with the @PATH"? What do you mean = by that? Hm, excuse my stupidity...

How do you configure = your ERXRouteRequestHandler? Something like = in er.rest.example.Application (ERRestRouteExample)? I'm always = doing something like:

ERXRouteRequestHandler routeRequestHandler =3D = new ERXRouteRequestHandler(ERXRouteRequestHandler.WO);
routeRequestHandler.addRoute(new ERXRoute(Person.ENTITY_NAME, = "/Person/{person:Person}", ERXRoute.Method.Put, PersonController.class, = "update"));

regards,
Peer



Am = 03.02.2021 um 09:40 schrieb Don Lindsay <webobjects-dev@wocommunity.org>:

Hello;

I am in development mode = right now.  I see the put coming into the server and I can get it = to go to the method using the @PUT annotation with the @PATH, but the = json never gets put into a key so I can=E2=80=99t get the object to = update.

Thanks,

Don

On Feb 3, 2021, at 02:17, Peer = Sandtner <webobjects-dev@wocommunity.org> wrote:

Hello Don,

are you using an Apache? = In my case I had to modify webobjects.conf:

# Specific to Apache 2.4
<Location = /cgi-bin/WebObjects/>
    <Limit GET POST PUT = OPTIONS >
  =     Require all granted
    </Limit>
    Require all = denied
</Location>   

Peer



Am 03.02.2021 um 07:21 schrieb = Don Lindsay <webobjects-dev@wocommunity.org>:

Hello;

I have a ERRest project. = Everything seems to be working except for when I update an entity the = updateAction never gets called.  I put breakpoints in the source = code on createAction, updateAction, indexAction, showAction. The method = that gets called for PUT is indexAction.  Am I doing something = wrong with the code, I took a look at the example apps in Project Wonder = and used them to create my boilerplate.
  
Thanks,

Don


The request from the developer tools in the = browser:

<PastedGraphic-1.png>


How = the data is being sent:

$.ajax({
url: '/cgi-bin/WebObjects/xxxxxx.woa/ra/TileV2',
= type: =E2=80=98PUT',
data: workingObject,
dataType: 'json',
= contentType: 'application/json',
success: function (data) = {
comp._currentTile =3D data;
console.log(JSON.stringify(data))
bootbox.alert({
= title: "Tile Save",
message: "Tile saved successfully",
centerVertical: = true
= });
comp.resetDirty();
comp.initialize(window.connectorsjson, window.tilejson);;
},
error: function (data) {
bootbox.alert({
= title: "Tile Save",
message: "Saving the tile failed, please try again = later",
= centerVertical: true
});
}
});



TileV2Controller.java

public class TileV2Controller extends BaseRestController = {

public = TileV2Controller(WORequest request) {
= super(request);
= // TODO Auto-generated constructor stub
}

= @Override
public = WOActionResults createAction() throws Throwable {
TileV2 tilev2 =3D = create(createInFilter());
= editingContext().saveChanges();
= return response(tilev2,outFilter());
= }
public = ERXKeyFilter createInFilter() {
= return ERXKeyFilter.filterWithAttributes();
= }
public = ERXKeyFilter outFilter() {
= ERXKeyFilter out = =3D createInFilter();
= return = out;
= }
/**
* = Returns the value of the "tile" variable from the route.
* @return
*/
= public TileV2 tilev2() {
= TileV2 tilev2 =3D routeObjectForKey("tileV2");
= tilev2.setTenant(((com.mozaic.app.Session)session()).get= Tenant());
return tilev2;
= }
/**
* The = query filter is used in indexAction to control what attributes and = relationships
= * you expose to qualifiers through query parameters
= * 
* = @return
*/
= public static ERXKeyFilter queryFilter() {
ERXKeyFilter filter =3D ERXKeyFilter.filterWithAllRecursive();
= filter.includeAll();
= return = filter;
= }
/**
* This = showFilter is used by indexAction and showAction and says to return all = attributes
= * of an TileV2, and for the owner, include all of its = attributes. 
= */
public = static = ERXKeyFilter showFilter() {
= ERXKeyFilter filter =3D ERXKeyFilter.filterWithAttributes();
= return = filter;
= }
/**
* The = updateFilter is used by updateAction and createAction and says to allow = updating any attributes of an
* TileV2.
* @return
*/
= public static ERXKeyFilter updateFilter() {
ERXKeyFilter = filter =3D = ERXKeyFilter.filterWithAttributes();
= return= filter;
= }
@Override
public WOActionResults = updateAction() {
= TileV2 tilev2 =3D = tilev2();
= update(tilev2, = updateFilter());
= editingContext().saveChanges();
= return response(tilev2, showFilter());
}

= @Override
public = WOActionResults destroyAction() throws Throwable {
TileV2 tilev2 =3D = tilev2();
= tilev2.delete();
= editingContext().saveChanges();
= return response(tilev2, showFilter());
}

= @Override
public = WOActionResults newAction() throws Throwable {
= TileV2 tilev2 =3D = TileV2.createTileV2(editingContext(), "New Description", null, "New Tile",  = ((com.mozaic.app.Session)session()).getTenant());
return response(tilev2, showFilter());
= }
@Override
public WOActionResults showAction() = {
return response(tilev2(), = showFilter());
= }
/**
* = indexAction uses an ERXRestFetchSpecification, which optionally allows = you to expose sorting, qualifying, and batching in query = parameters 
= */
@Override
public WOActionResults indexAction() = {
if (isSchemaRequest()) = {
return = schemaResponse(showFilter());
= }
= ERXRestFetchSpecification<TileV2> fetchSpec =3D new = ERXRestFetchSpecification<>(TileV2.ENTITY_NAME, null, null, queryFilter(), TileV2.NAME.ascs(), = 25);
return response(fetchSpec, showFilter());
= }
}







= --Apple-Mail=_8740C871-A82C-4A1D-8988-304769CBAD4E--