Unable to install apiproxy with npm modules

I am trying to deploy api-proxy using grunt plugin. This apiproxy has npm modules defined in package.json

{
  "name": "proxy-name",
  "version": "1.0.0",
  "description": "Some API",
  "main": "app.js",
  "author": "API Team",
  "license": "Some License",
  "dependencies": {
    "express": "^4.12.3",
    "request": "^2.55.0",
    "node-sass-middleware": "^0.5.0"
  }
}

We are using on-prem Version 4.14.07.00 and getting below error.

Running "installNpmRevision:4" (installNpmRevision) task
[D] Task source: grunt/tasks/installNpmRevision.js
curl -X POST http://mgmt-server:8080/v1/o/Org/apis/proxy-name/revisions/4/npm -d '"command=install"'
[D] 500
[D] npm ERR! 
at /opt/apigee4/share/apigee/lib/node_modules/npm/node_modules/lockfile/lockfile.js:182 (anonymous)
npm ERR! at /Users/Apigee/src/noderunner/target/checkout/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:107 (anonymous)
npm ERR! at /Users/Apigee/src/noderunner/target/checkout/node10/node10src/src/main/javascript/io/apigee/trireme/node10/main/trireme.js:816 (submitDomainTick)
npm ERR! 
npm ERR! If you need help, you may report this entire log,
npm ERR! including the npm and node versions, at:
npm ERR!     <http://github.com/npm/npm/issues>


npm ERR! System Trireme Trireme
npm ERR! command "./node" "/opt/apigee4/share/apigee/lib/node_modules/npm/cli.js" "--loglevel" "error" "--registry" "https://registry.npmjs.org/" "--cache" "/opt/apigee4/var/log/apigee/management-server/work/npm-cache" "--ignore-scripts" "true" "--bin-links" "false" "--json" "install"
npm ERR! cwd /opt/apigee4/var/log/apigee/management-server/work/npm/npm1805312746234641835.tmp
npm ERR! node -v v0.10.24
npm ERR! npm -v 1.4.3
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /opt/apigee4/var/log/apigee/management-server/work/npm/npm1805312746234641835.tmp/npm-debug.log
npm ERR! not ok code 0

We are seeing errors in /opt/apigee4/var/log/apigee/management-server/logs/system.log

2015-05-14 10:14:55,148 org:OrgName env:dev Apigee-Main-15 ERROR REST - ExceptionMapper.toResponse() : Returning error response : ErrorResponse{errorCode = distribution.ApplicationNotDeployed, errorMessage = Application apiproxy-name is not deployed in environment dev of organization OrgName}
2015-05-14 10:14:55,219 org:OrgName env: Apigee-Main-31 INFO  c.a.m.c.b.ApplicationRevisionFactory - ApplicationRevisionFactory.importAndValidate() : ApplicationRevisionFactory.importAndValidate() - validating a bundle with revision ID - 4
2015-05-14 10:14:56,202 org:OrgName env: Apigee-Main-12 INFO  NODESCRIPT - DependencyAPI.runNpm() : Executing "npm install" for apiproxy-name in /opt/apigee4/var/log/apigee/management-server/work/npm/npm1805312746234641835.tmp
2015-05-14 10:14:57,175 org:OrgName env: Apigee-Main-12 INFO  NODESCRIPT - DependencyAPI.runNpm() : npm install completed with exit code 1
2015-05-14 10:14:57,176 org:OrgName env: Apigee-Main-12 ERROR REST - CustomJAXRSInvoker.performInvocation() : CustomJAXRSInvoker.performInvocation : Method com.apigee.gateway.services.nodescript.dependency.DependencyAPI.updateDependenciesForm threw an exception. 
javax.ws.rs.WebApplicationException: null
	at com.apigee.gateway.services.nodescript.dependency.DependencyAPI.makeResult(DependencyAPI.java:121) ~[nodescript-1.0.0.jar:na]
	at com.apigee.gateway.services.nodescript.dependency.DependencyAPI.updateDependenciesInternal(DependencyAPI.java:240) ~[nodescript-1.0.0.jar:na]
	at com.apigee.gateway.services.nodescript.dependency.DependencyAPI.updateDependenciesForm(DependencyAPI.java:181) ~[nodescript-1.0.0.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_45]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_45]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_45]
	at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_45]
	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173) [cxf-rt-core-2.4.7.jar:2.4.7]
	at com.apigee.rest.framework.CustomJAXRSInvoker.performInvocation(CustomJAXRSInvoker.java:126) ~[rest-1.0.0.jar:na]
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89) [cxf-rt-core-2.4.7.jar:2.4.7]
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:165) [cxf-rt-frontend-jaxrs-2.4.7.jar:2.4.7]
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:241) [cxf-rt-frontend-jaxrs-2.4.7.jar:2.4.7]
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:92) [cxf-rt-frontend-jaxrs-2.4.7.jar:2.4.7]
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58) [cxf-rt-core-2.4.7.jar:2.4.7]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) [na:1.6.0_45]
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) [na:1.6.0_45]
	at java.util.concurrent.FutureTask.run(FutureTask.java:138) [na:1.6.0_45]
	at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37) [cxf-rt-core-2.4.7.jar:2.4.7]
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106) [cxf-rt-core-2.4.7.jar:2.4.7]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263) [cxf-api-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-rt-core-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:207) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:152) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:114) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:185) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:108) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [servlet-api-3.0.20100224.jar:na]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:164) [cxf-rt-transports-http-2.4.7.jar:2.4.7]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:558) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:488) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:973) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:417) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:907) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.Server.handle(Server.java:350) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:442) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:941) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:801) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:51) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:586) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:44) [jetty-webapp-8.0.4.v20111024.jar:8.0.4.v20111024]
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) [na:1.6.0_45]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) [na:1.6.0_45]
	at java.lang.Thread.run(Thread.java:662) [na:1.6.0_45]
2015-05-14 10:14:57,177 org:OrgName env: Apigee-Main-12 ERROR REST - ExceptionMapper.toResponse() : Error occurred : null

Solved Solved
1 6 820
1 ACCEPTED SOLUTION

Not applicable

Thanks, @Vineet Bhatia. I can see the failing cURL command is using Apigee NPM management api, which is in charge of installing npm modules in Apigee Edge. Please try passing --upload-modules flag to the grunt command, which will bundle all npm modules up and incorporate them into the zip file that gets deployed in Edge. The bundle will be a bit larger though.

curl -X POST http://mgmt-server:8080/v1/o/Org/apis/proxy-name/revisions/4/npm -d '"command=install"'

Hope it helps!

View solution in original post

6 REPLIES 6

Not applicable

Thanks, @Vineet Bhatia. I can see the failing cURL command is using Apigee NPM management api, which is in charge of installing npm modules in Apigee Edge. Please try passing --upload-modules flag to the grunt command, which will bundle all npm modules up and incorporate them into the zip file that gets deployed in Edge. The bundle will be a bit larger though.

curl -X POST http://mgmt-server:8080/v1/o/Org/apis/proxy-name/revisions/4/npm -d '"command=install"'

Hope it helps!

Thanks @dzuluaga adding --upload-modules worked! That was exactly what I was looking for because if we were to use "private npm repo" we would need a way to upload npm modules and not run npm install as that won’t work when using apigee in the cloud (it won’t be able to reach our "private" npm repo).

So with this approach we need to run npm install in the node folder as part of the grunt build?

That's correct. Apigee Edge may not be able to retrieve private NPM modules since .npmrc config file changes might not be currently supported. @arghya das Please keep me honest 🙂

For developers environments, this shouldn't be a problem as they'd mostly have control of their laptops. So, they can fetch NPM modules without issues. However, you bring a good point for other cloud environments for Continuous Integration (CI) e.g. Jenkins, Travis, etc. In those cases, you also depend on the capabilities of the vendor again. I haven't run with this issue yet. However, I know that others did. @Kristopher Kleva if you want to comment on it, I recall your team retrieves dependencies by fetching dependencies with the following tweak to the shell task:

npm_install: {
                options: {
                    stderr: false,
                    failOnError: true
                },
                command: 'npm install --prefix ./target/apiproxy/resources/node'
            }

@dzuluaga This works, one small issue on the deployed api-proxy the unzipped npm modules are present along with zipped. Is there a way to either exclude the npm_modules folder from bundle zip or delete npm_modules folder after zipping npm_modules.zip?

Good catch. Thanks @Vineet Bhatia. I think I've just fixed it for everyone in the latest version of Yeoman API Proxy generator. You can update to the latest version 0.0.12, by calling this:

npm update generator-apigee-deploy-grunt-api -g  

FYI: The fix was to use the prefix on the node source folder instead of the target one. So, you'll find that Gruntfile now contains a new shell task like this one:

shell: {
   apigee_npm_node_modules : { command: "npm install --prefix './node'" }
}

And this task/target is executed under buildApiBundle.

Please let me know if this works or not.

FYI: In the future, rather than adding a note as an additional "Answer" to your own question, you can add your "thanks..." and additional info as a COMMENT to the actual answer provided. Also we encourage you to click "Accept" on an answer if it is acceptable and helpful to you.