The AppDynamics Node.js Agent has multiple native dependencies which are keyed to particular major versions of Node.js. As such, the Agent works somewhat differently from other NPM packages.
For example, when downloading our package from NPM, it will request a dependency appdynamics-native which will work only for a particular major version of Node.js. As we want to support multiple major versions of Node.js, we need some way to distribute multiple artifacts for each dependency; one for each major version of Node.js.
NPM by itself does not provide a facility for this, but it does allow us to specify our own repository for the dependencies. We leverage this capability to automatically serve the correct dependency artifacts for the particular major version of Node.js requesting the Agent.
The repository lives at packages.appdynamics.com. It accepts incoming dependency requests from the NPM client, which contain a user-agent string, e.g. npm/3.10.10 node/v6.10.3 linux x64. Using this user-agent string, the repository redirects the request to the appropriate artifact URL, which will serve the dependency back to the client if it exists. If the user-agent string is malformed or missing, or the repository has no artifact for the version, platform, or architecture specified, the repository will return a 403 error code instead of the artifact. This 403 will show up on the NPM command line.
Dependency artifacts are matrixed on Node.js version, platform, and architecture. This means that the same dependency has many different potential artifacts, depending on the user-agent specified.
Manipulating the user-agent string can be very helpful in resolving deployment issues. Typically one wants to mirror the user-agent from a target server to a build system. There are two key commands which enable this:
$ npm config get user-agent
npm/3.10.10 node/v6.11.0 darwin x64
$ npm config set user-agent "npm/3.10.10 node/v6.10.3 linux x64"
$ npm config get user-agent
npm/3.10.10 node/v6.10.3 linux x64
Changing the user-agent changes the AppDynamics agent which is installed through NPM. In the above example, we've gone from requesting the version-6/OSX/x64 agent to requesting the version-6/linux/x64 agent.
In the case of needing to match a build machine's user-agent to a target server's, the procedure is to extract the target server's user agent with NPM config get user-agent, copy it over to the build machine, then set it there with npm config set user-agent "<copied user agent string>". All subsequent builds will now download the correct AppDynamics native dependencies.
npm-shrinkwrap.json / package-lock.json
When using lockfiles with NPM and AppDynamics, one must be very careful to maintain user-agent parity between any machines sharing the lockfile. For example, a developer installs AppDynamics locally using npm install. This mutates the package-lock.json file for the project, which they then check into source control. Later, a build machine checks out the same commit, and tries to install using the lockfile. This fails with an integrity error, because the developer checked in the lockfile with AppDynamics OSX dependencies, and the build machine runs Linux. As above, the artifacts are different, and so have different integrity values. The best way to ensure no integrity conflict arises is to always ensure that your lockfiles have been built with the same NPM user-agent active.