2017-07-11 97 views
5

Potrzebuję wdrożyć usługę sieci mydlanej za pomocą funkcji firebase. Znalazłem moduł o nazwie soap-node soap-module-github, który wydaje się obiecujący, ponieważ integruje się z ekspresowym, a firebase mówi, że używa wyrażenia dla wywołań http, ale problemem jest to, że nie wiem jak zintegrować ten moduł z funkcjami firebase, ponieważ, Funkcje firebase są obsługiwane przez wywołania http wykonywane przez klientów, każda pomoc byłaby bardzo pomocna.Jak korzystać z funkcji chmury w Firebase, aby napisać usługę SOAP?

Oto kod udało mi się stworzyć tak daleko:

var fs = require('fs'), 
    soap = require('soap'), 
    express = require('express'), 
    lastReqAddress; 
    var server = express(); 
    service = { 
     StockQuoteService: { 
      StockQuotePort: { 
       GetLastTradePrice: function (args, cb, soapHeader) { 
        if (soapHeader) 
         return { 
          price: soapHeader.SomeToken 
         }; 
        if (args.tickerSymbol === 'trigger error') { 
         throw new Error('triggered server error'); 
        } else if (args.tickerSymbol === 'Async') { 
         return cb({ 
          price: 19.56 
         }); 
        } else if (args.tickerSymbol === 'SOAP Fault v1.2') { 
         throw { 
          Fault: { 
           Code: { 
            Value: "soap:Sender", 
            Subcode: { 
             value: "rpc:BadArguments" 
            } 
           }, 
           Reason: { 
            Text: "Processing Error" 
           } 
          } 
         }; 
        } else if (args.tickerSymbol === 'SOAP Fault v1.1') { 
         throw { 
          Fault: { 
           faultcode: "soap:Client.BadArguments", 
           faultstring: "Error while processing arguments" 
          } 
         }; 
        } else { 
         return { 
          price: 19.56 
         }; 
        } 
       }, 

       SetTradePrice: function (args, cb, soapHeader) {}, 

       IsValidPrice: function (args, cb, soapHeader, req) { 
        lastReqAddress = req.connection.remoteAddress; 

        var validationError = { 
         Fault: { 
          Code: { 
           Value: "soap:Sender", 
           Subcode: { 
            value: "rpc:BadArguments" 
           } 
          }, 
          Reason: { 
           Text: "Processing Error" 
          }, 
          statusCode: 500 
         } 
        }; 

        var isValidPrice = function() { 
         var price = args.price; 
         if (isNaN(price) || (price === ' ')) { 
          return cb(validationError); 
         } 

         price = parseInt(price, 10); 
         var validPrice = (price > 0 && price < Math.pow(10, 5)); 
         return cb(null, { 
          valid: validPrice 
         }); 
        }; 

        setTimeout(isValidPrice, 10); 
       } 
      } 
     } 
    }; 
    var wsdl = fs.readFileSync(__dirname + '/../wsdl/stockquote.wsdl', 'utf-8').toString(); 
    server = express(); 

    soapServer = soap.listen(server, '/stockquote', service, wsdl); 

Oto stockquote.wsdl:

<wsdl:definitions name="StockQuote" 
     targetNamespace="http://example.com/stockquote.wsdl" 
     xmlns:tns="http://example.com/stockquote.wsdl" 
     xmlns:xsd1="http://example.com/stockquote.xsd" 
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 

<wsdl:types> 
    <xsd:schema targetNamespace="http://example.com/stockquote.xsd" xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"> 
     <xsd:element name="TradePriceRequest"> 
      <xsd:complexType> 
       <xsd:all> 
        <xsd:element name="tickerSymbol" type="string"/> 
       </xsd:all> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="TradePrice"> 
      <xsd:complexType> 
       <xsd:all> 
        <xsd:element name="price" type="float"/> 
       </xsd:all> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="TradePriceSubmit"> 
      <xsd:complexType> 
       <xsd:all> 
        <xsd:element name="tickerSymbol" type="string"/> 
        <xsd:element name="price" type="float"/> 
       </xsd:all> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="valid" type="boolean"/> 
    </xsd:schema> 
</wsdl:types> 

<wsdl:message name="GetLastTradePriceInput"> 
    <wsdl:part name="body" element="xsd1:TradePriceRequest"/> 
</wsdl:message> 

<wsdl:message name="GetLastTradePriceOutput"> 
    <wsdl:part name="body" element="xsd1:TradePrice"/> 
</wsdl:message> 

<wsdl:message name="SetTradePriceInput"> 
    <wsdl:part name="body" element="xsd1:TradePriceSubmit"/> 
</wsdl:message> 

<wsdl:message name="IsValidPriceInput"> 
    <wsdl:part name="body" element="xsd1:TradePrice"/> 
</wsdl:message> 

<wsdl:message name="IsValidPriceOutput"> 
    <wsdl:part name="body" element="xsd1:valid"/> 
</wsdl:message> 

<wsdl:portType name="StockQuotePortType"> 
    <wsdl:operation name="GetLastTradePrice"> 
     <wsdl:input message="tns:GetLastTradePriceInput"/> 
     <wsdl:output message="tns:GetLastTradePriceOutput"/> 
    </wsdl:operation> 
    <wsdl:operation name="SetTradePrice"> 
     <wsdl:input message="tns:SetTradePriceInput"/> 
    </wsdl:operation> 
    <wsdl:operation name="IsValidPrice"> 
     <wsdl:input message="tns:IsValidPriceInput"/> 
     <wsdl:output message="tns:IsValidPriceOutput"/> 
    </wsdl:operation> 
</wsdl:portType> 

<wsdl:binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType"> 
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 
    <wsdl:operation name="GetLastTradePrice"> 
     <soap:operation soapAction="http://example.com/GetLastTradePrice"/> 
     <wsdl:input> 
      <soap:body use="literal"/> 
     </wsdl:input> 
     <wsdl:output> 
      <soap:body use="literal"/> 
     </wsdl:output> 
    </wsdl:operation> 
    <wsdl:operation name="SetTradePrice"> 
     <soap:operation soapAction="http://example.com/SetTradePrice"/> 
     <wsdl:input> 
      <soap:body use="literal"/> 
     </wsdl:input> 
    </wsdl:operation> 
    <wsdl:operation name="IsValidPrice"> 
     <soap:operation soapAction="http://example.com/IsValidPrice"/> 
     <wsdl:input> 
      <soap:body use="literal"/> 
     </wsdl:input> 
    </wsdl:operation> 
</wsdl:binding> 

<wsdl:service name="StockQuoteService"> 
    <wsdl:port name="StockQuotePort" binding="tns:StockQuoteSoapBinding"> 
     <soap:address location="http://localhost:5002/stockquote"/> 
    </wsdl:port> 
</wsdl:service> 

Mam google bardzo dobry po prostu nie znaleźć na jakiejś ścieżce, wyszukiwałem również funkcje Google i ich integrację z mydłem, ponieważ funkcje firebase to tylko funkcje Google Cloud używane dla firebase

+0

czy znalazłeś rozwiązanie? – faruk

Odpowiedz

2

wgląd do kodu źródłowego node-soap, powinieneś być w stanie bezpośrednio przekazać _requestListener do funkcji cloud onRequest funkcję:

exports.stockquote = functions.https.onRequest(soapServer._requestListener) 
+0

próbowałem tego i otrzymuję komunikat o błędzie "nie można odczytać właściwości" log "z undefined' – faruk

1

Można użyć express z chmurą funkcji now:

server = express(); 
server.listen(5002, function() { 
    soap.listen(server, '/stockquote', service, wsdl); 
}); 

exports.stockquote = functions.https.onRequest(server); 

umieścić trasa w firebase.json:

"rewrites": [ 
    { 
    "source": "/stockquote", 
    "function": "stockquote" 
    } 
] 

Podczas testowania na kliencie za pomocą javascript don ' t zapomnij zmienić punkt końcowy, aby zastąpić localhost w WSDL:

var soap = require('soap'); 
var url = 'https://[your-project-id].firebaseapp.com/stockquote?wsdl'; 
var args = {tickerSymbol: 'some symbol', price: 100.0}; 

var options = { 
    'endpoint' : 'https://[your-project-id].firebaseapp.com/stockquote' 
}; 

soap.createClient(url, options, function(err, client) { 
    if (err) throw err; 
    //print service in json 
    console.log(client.describe()); 
    client.GetLastTradePrice(args, function(err, result) { 
     if(err) 
      console.log("err = "+ err.message); 
     console.log(result); 
     res.status(200).send(result); 
    }); 
}); 
2

Jesteś na właściwej drodze,

Jeśli chcesz ścieżki Twój GCF serwera być http://myfunctions.domain.com/stockquote/

wtedy Twoja ostatnia linia w pliku js powinny być soapServer = soap.listen(server, '/', service, wsdl) a następnie po tym, w funkcji Google cloud index.js wpisać:

exports.stockquote = functions.https.onRequest(server)

Musisz upewnić się, że twoje żądania SOAP przechodzą do punktu końcowego z końcowym ukośnikiem na końcu. Jeśli nie masz kontroli nad istniejącymi klientami, możesz dodać własną procedurę obsługi adresów URL, która obejrzy adres URL i doda adres / do adresu URL otrzymanego przez tę funkcję.

tj .: exports.stockquote = functions.https.onRequest(gcfURLHandler(server));

gdzie gcfURLHandler jest zdefiniowany jako

function gcfURLHandler(handler){ 
    return (req, res) => { 
     if(!req.url || !req.path) { 
      req.url = "/" + (req.url || ''); 
     } 
     handler(req, res) 
    } 
} 

zorientowaliśmy się od komentarza here. (który ma również inne wskazówki w oryginalnym kodzie)

Pracowałem nad tym ostatnim tygodniem i zobaczyłem pytanie bez odpowiedzi.Trzeba było dużo kopać, żeby w końcu to rozgryźć. Mam nadzieję, że pomoże to innym, którzy chcą zrobić to samo!