Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    RestHandler drops all not primaryKey criteria/values in a remove operation

    Hi isomorphic, i'm trying to perform a remove operation via Rest but when the RestHandler process the request it drops all not primaryKey criteria/values.

    SC Version:
    v110p_2016-12-19

    This is my JSON Request:

    Code:
    {
      "data": {
        "uid": null,
        "mail": "test@mail.com",
        "commonName": "test",
        "nome": "test",
        "gruppi": "gruppo_test",
        "shortName":"Primary key value",
        "cognome": "test",
        "NOME_GRUPPO": "ROLE_GRUPPO_TEST"
      },
      "dataSource": "TEST_REMOVE",
      "operationType": "remove"
    }
    In the dataSource I overwrited the remove operation to pass through a DMI in which i expect the entire record sent inside the JSON request, but when i perform this call, after that the RestHandler process the request to construct the dsRequest if i watch inside the criteria (dsRequest.getCriteria()) or values (dsRequest.getValues()) there is only the PrimaryKey value, in this case the "shortName" value. other values have been removed.

    I've also tried to add "allowMultiUpdate" or "providesMissingKeys" on the operationBinding but i obtain the same result.


    My RestHandler
    Code:
    package it.test.rest;
    
    
    import com.isomorphic.datasource.DSRequest;
    import com.isomorphic.datasource.DSResponse;
    import com.isomorphic.log.Logger;
    import com.isomorphic.rpc.RPCManager;
    import com.isomorphic.servlet.RESTHandler;
    import com.isomorphic.servlet.RequestContext;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class RestService extends RESTHandler {
        private Logger log = new Logger(RestService.class.getName());
    
        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            log.debug("entra in doPost");
            super.doPost(request, response);
        }
    
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            log.debug("entra in doGet");
            super.doGet(request, response);
        }
    
        @Override
        public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            log.debug("entra in processRequest, metodo = " + request.getMethod());
            super.processRequest(request, response);
        }
    
        @Override
        public DSResponse handleDSRequest(DSRequest dsRequest, RPCManager rpc, RequestContext context) throws Exception {
            try {
                HttpServletRequest httpServletRequest = dsRequest.getHttpServletRequest();
    
                log.debug("Richiesta REST, method: " + httpServletRequest.getMethod() + ", dataSource = " + dsRequest.getDataSourceName() + ", operationType: " + dsRequest.getOperationType());
                DSResponse dsResponse = super.handleDSRequest(dsRequest, rpc, context);
    
                return dsResponse;
            } catch (Exception e) {
                log.error("Eccezione", e);
                throw e;
            }
        }
    
    }

    My DataSource:
    Code:
    <DataSource xmlns="http://www.smartclient.com/schema"
                ID="TEST_REMOVE" dropExtraFields="false" serverType="generic">
    
        <fields>
            <field name="shortName" type="text" primaryKey="true"/>
            <field name="uid" type="text"/>
            <field name="commonName" type="text"/>
            <field name="name" type="text"/>
            <field name="surname" type="text"/>
            <field name="mail" type="text"/>
            <field name="groups" type="text"/>
        </fields>
    
        <operationBindings>
            <operationBinding operationType="remove">
                <serverObject lookupStyle="new" className="it.test.DMI.TestRemoveDMI"/>
            </operationBinding>
        </operationBindings>
    
    </DataSource>

    my DMI
    Code:
    package it.test.DMI;
    
    import com.isomorphic.datasource.DSRequest;
    import com.isomorphic.datasource.DSResponse;
    import com.isomorphic.rpc.RPCManager;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.*;
    
    
    public class TestRemoveDMI {
        public DSResponse fetch(DSRequest dsRequest, HttpServletRequest request, RPCManager rpcManager) {
            DSResponse dsResponse = new DSResponse();
            dsResponse.setData(new ArrayList<>());
            return dsResponse;
        }
    
        public DSResponse remove(DSRequest dsRequest, HttpServletRequest request, RPCManager rpcManager) throws Exception {
            DSResponse dsResponse = new DSResponse();
            Map criteriaTemp = dsRequest.getValues();
    
            if(criteriaTemp.get("mail") == null){
                dsResponse.setFailure("mail parameter cannot be null");
            } else {
                dsResponse.setSuccess();
            }
    
            return dsResponse;
        }
    
    }
    Last edited by simokris; 21 Dec 2016, 09:46.

    #2
    Only the PK value is used in the execution of the DSRequest (eg, in forming SQL). The other values are available as DSRequest.oldValues.

    Bear in mind these values come from the browser, so they cannot be relied upon for security checks.

    Comment


      #3
      Hmm.. I Tried to modify the DMI and i tried to perform the same request via SC ListGrid. Well, if i perform a remove from a SC ListGrid bound on "TEST_REMOVE" dataSource, i can retrieve the entire record using these methods: dsRequest.getClientSuppliedCriteria() or dsRequest.getClientSuppliedValues() or, as you said before, into dsRequest.getOldValues().

      But, Why? is this by design? Why cannot i pass the entire record on a Rest remove?

      If i cannot pass the entire record also I cannot perform a multiUpdate (multiRemove)
      Last edited by simokris; 21 Dec 2016, 08:58.

      Comment


        #4
        Your JSON request doesn't include oldValues. It just tries to stick the entire record into data, which is used as criteria. In the absence of allowMultiIUpdate=true on your operationBinding, again only the PK will be used.

        Comment


          #5
          So the solution consists of adding "allowMultiUpdate=true" on the operationBinding and adding oldValues on the JSONRequest and in the end get the entire record via dsRequest.getOldValues, is it correct?
          So the remove operation performed via client call or via REST call is completely different, because in a client call you can get the entire record using dsRequest.getClientSuppliedCriteria without using allowMultiUpdate, but in a REST call you must use allowMultiUpdate to pass the entire record and getting it using a different method.

          I'm not really sure that is completely correct because i tried this solution and if i add the oldValues in the JSONRequest i can get the entire record into the DMI using dsRequest.getOldValues, but i can get the entire record in this way both using allowMultiUpdate or not. So allowMultiUpdate it is unnecessary.

          Now i'm really confused, can you explain me the correct way to pass the entire record, inside a remove JSONRequest, and get the record into a DMI?

          Thanks.

          Comment


            #6
            allowMultiUpdate does what the docs say it does - it allows multiple fields to appear in the criteria, without requiring the primaryKey.

            Although you haven't said so, your grid is most likely using the "scServer" protocol. That protocol allows you to separately specify criteria vs values so that you could provide a multi-field criteria for a "remove" (as a completely orthogonal concern from allowMultiUpdate, which has the same effect regardless of the protocol used for the request). There is currently no way to do this with the REST protocol, but again, the "oldValues" metadata field allows you to get the information to the server, in case you need it for a DMI or similar.

            Comment

            Working...
            X