Git Product home page Git Product logo

sample-spring-boot-api-service's Introduction

Zowe REST API SDK and Sample Service · CircleCI Quality Gate Status download Coverity Scan Build Status

This project provides:

  1. Sample REST API service that run on z/OS and can use native z/OS interfaces
  2. SDK (software development kit) for creating such services that includes:

Getting Started

Developing New REST API Service

Follow the instructions at Zowe Sample API Service.

Demo

Deploying the sample REST API to z/OS under 5 minutes

asciicast

Documentation for SDK Developers

License

The repository is dual-licensed under Apache License 2.0 and Eclipse Public License - v 2.0.

sample-spring-boot-api-service's People

Contributors

dependabot[bot] avatar dkelosky avatar jandadav avatar jirkaaichler avatar markackert avatar plavjanik avatar t1m0thyj avatar vitekvlcek-broadcom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sample-spring-boot-api-service's Issues

Warning about a Gradle features deprecated in 6.0

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings

Method not allowed missing error message?

Maybe I'm missing something, but I removed any custom exception handlers in favor of what is being done in the commons jar:

https://github.com/zowe/sample-spring-boot-api-service/blob/master/zowe-rest-api-commons-spring/src/main/java/org/zowe/commons/spring/CustomRestExceptionHandler.java

For "403" I get the following response:

{
    "messages": [
        {
            "messageType": "ERROR",
            "messageNumber": "ZWEAS403",
            "messageContent": "The user is not authorized to the target resource: Access is denied",
            "messageKey": "org.zowe.commons.rest.forbidden",
            "messageInstanceId": "11a3da12-4895-42b5-81b1-e8e5e092c88d"
        }
    ]
}

For "405" I get no payload response? For us, its really not a big deal to have a message in the response body, the HTTP status is enough, but just wanted to check if this is expected behavior?

Use the common logging format in native code

  • Try to use a similar format in the C/C++ code
  • Ideally, put the function/macro to the commons library
2019-09-03 04:02:37.856 <ZWEASA1:main:33950015> PLAPE03 (org.zowe.commons.spring.ServiceStartupEventHandler:25) INFO Zowe Sample API Service has been started in 10.204 seconds
[DEBUG] Input - id: 1 content: Hello, world!```

Build and test native code on Zowe z/OS system

As the SDK developer, I would like the CIt to build the native code on z/OS.

Acceptance criteria:

  • The .so files are built by the CircleCI calling zowe-api-dev against river.zowe.org

Security context switching on z/OS

Migrate the code for security context switching on z/OS

Depends on #4

The original source code has been added by https://github.gwd.broadcom.net/MFD/ca-sample-restapi-service/pull/28

As a developer who is developing REST API service, I want to run Java code under the same user ID the s user using REST API, so that the code can access mainframe resources only accessible by that user without the need to setup PassTickets.

Original acceptance criteria:

  • It is possible to run some Java code under the mainframe security environment for the user that is authenticated to the REST API
  • This is done without requiring PassTickets to be set up by leveraging pthread_security_applid_np() function with function code __DAEMON_SECURITY_ENV that requires permission to BPX.DAEMON
  • It requires being executed on z/OS, on PC or Mac a dummy implementation can be used

Migrate documentation from DocOps

Example of Callable Context Switch

We need an example "callable" endpoint in the SDK tested against all three security subsystems (modeled after wrapRunnableInEnvironmentForAuthenticatedUser) and understand why one appears to need BPX.DAEMON and the other does not on Top Secret

Faster uploads to z/OS

As a developer of the REST API, I would like to test or debug my REST API on z/OS without losing focus while waiting minutes for JAR or native code upload to finish.

  • Smart upload (only changed files - tool remembers the last uploaded file)
  • Smart JAR update (only changed files in a JAR are transferred and updated on z/OS) - it can save

Support access control check for DATASET resource class

The PlatformAccessControl class and its underlying implementation __check_resource_auth_np() support the general resources only. In particular, the class can not specify DATASET.

But checking access to DATASET can be useful.

Acceptance criteria:

  • The PlatformSecurityService implementation works well with DATASET resource class and can be used to check access to MVS datasets.

Implementation tips:

  • Use assembler code that calls RACROUTE REQUEST=AUTH macro
  • Call the assembler code from new JNI function in the zowe-sdk-secur module. This module is program-controlled so it can use RACROUTE REQUEST=AUTH functionality

jzos in the sample

It might make sense to include some jzos stuff in the sample? It's probably pretty common for folks to need those capabilities.

z/OS authorization checks

As a developer of the REST API, I would like to protect REST API endpoints or parts of my code by SAF resources.

  • API to do authorization checks
  • Check that the application has required permissions for authentication at startup
  • Authorization implementation using the Java SAF APIs (DATASET resource class is not in the scope of this story)
  • Integration with Spring Security

Support internationalization of Swagger documentation

As an API developer, I would like to be able to localize the Swagger documentation that my API is generating.

  • It is possible to define localization for text in the Springfox annotations
  • The localization is chosen by the Accept-Language header or lang query parameter
  • Validation that Swagger UI component does not prevent the flow of Accept-Language header from the browser to the API service
  • Swagger UI component localization is not part of the story

Patched JAR does not start when a commons JAR is updated

Spring Boot requires JARs inside the fat JAR to be stored without compression.

Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/zowe-rest-api-commons-spring-0.0.0-SNAPSHOT.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file

The workaround is to use:

zowe-api-dev deploy --force

Full error log:

Starting application in SSH z/OS UNIX session using command '/sys/java64bt/v8r0m0/usr/lpp/java/J8.0_64/bin/java -Djava.library.path="./lib:${LIBPATH}" -Xquickstart -jar bin/zowe-rest-api-sample-spring.jar --spring.config.additional-location=file:etc/application.yml' in directory '/a/plape03/zowe-rest-api-sample-spring'
ℹ You can stop it using Ctrl+C
Executing z/OS UNIX command '/sys/java64bt/v8r0m0/usr/lpp/java/J8.0_64/bin/java -Djava.library.path="./lib:${LIBPATH}" -Xquickstart -jar bin/zowe-rest-api-sample-spring.jar --spring.config.additional-location=file:etc/application.yml' in directory /a/plape03/zowe-rest-api-sample-spring

$ Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/zowe-rest-api-commons-spring-0.0.0-SNAPSHOT.jar
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:87)
        at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:69)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/zowe-rest-api-commons-spring-0.0.0-SNAPSHOT.jar'
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:258)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:244)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:104)
        ... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/zowe-rest-api-commons-spring-0.0.0-SNAPSHOT.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:284)
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:266)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:255)
        ... 6 more
Error: empty JSON response from Zowe CLI
    at zoweSync (~/workspace/github.com/zowe/sample-spring-boot-api-service/zowe-api-dev/src/zowe.ts:65:23)
    at execSshCommand (~/workspace/github.com/zowe/sample-spring-boot-api-service/zowe-api-dev/src/zowe.ts:152:12)
    at Object.execSshCommandWithDefaultEnv (~/workspace/github.com/zowe/sample-spring-boot-api-service/zowe-api-dev/src/zowe.ts:161:12)
    at Start.run (~/workspace/github.com/zowe/sample-spring-boot-api-service/zowe-api-dev/src/commands/start.ts:59:13)
    at Start._run (~/workspace/github.com/zowe/sample-spring-boot-api-service/zowe-api-dev/node_modules/@oclif/command/lib/command.js:44:31)

java.lang.UnsatisfiedLinkError for JNI Code with "zos" profile

When adding the zos profile to configuration and calling native code through JNI, you get UnsatisfiedLinkError during invocation. When starting through JCL, messages like this appear in the job log:

08.14.25 JOB51197  TSS7003W Password Will Expire on 07/01/19                                
08.14.25 JOB51197  TSS7000I xxxxxxx Last-Used 26 Jun 19 06:23 System=xxxx Facility=ZOSMF    
08.14.25 JOB51197  TSS7001I Count=00423 Mode=Fail Locktime=None Name=KELOSKY, DANIEL L      
08.14.25 JOB51197  BPXP015I HFS PROGRAM ./libwtojni.so IS NOT MARKED PROGRAM CONTROLLED.    
08.14.25 JOB51197  TSS7236E ENVIRONMENT IS CONTROLLED - UNIX MARK UNCONTROLLED REQUEST RE   
08.14.25 JOB51197  JECTED                                                                   
08.14.25 JOB51197  BPXP014I ENVIRONMENT MUST REMAIN CONTROLLED FOR DAEMON (BPX.DAEMON) PR   
08.14.25 JOB51197  OCESSING.                                                                

Removing the zos from the profile "resolves" the UnsatisfiedLinkError.

Error and warning message format in the API response

  • Migrate the documentation about message format to the documentation of the sample service
  • Provide practical instructions and examples of how to use it in the following scenarios:
    • Response for the REST API with errors and warnings
    • How to add a new message
    • How to throw exceptions in the code and how to convert them to REST API responses (PetControllerExceptionHandler.java which provides a recommended style)
    • Provide links to good tutorials about error handling in Spring and Java
    • An internal message is written to the server log
      • Improve the generating of the message instance ID (directly in the ApiMessage class)

Uncaught Exception Example

The API doc states:
"Unexpected errors does not need to be handled or caught by your REST controller. If your controller throws an Exception or RuntimeException then Spring exception handler (customized by CustomRestExceptionHandler in the commons library) will convert the exception into a standardized format. "

Is information available on what content is produced by the commons package for an uncaught exception? For example, does it produce a stack trace, or other detailed information?

Reported by @gejohnston

Self-contained token-based authentication for development and testing purposes

The goal of this story is to enable developers who are using the SDK to use token-based authentication in their REST API services.

Note:

  • Start simple - no JWT, just cryptographically safe randoms string, initially in-memory, later persisted
  • This is the building block for APIML-based authentication when the basic self-contained provider is replaced by calls to ZAAS just by the means of the API service configuration

Requires #80

URI Pattern Inside and Outside of API ML

If we follow this:

   routes:
        - gatewayUrl: api/v1
          serviceUrl: /api/v1

We may have an endpoint outside of the API ML that is: /api/v1/status.

Then, through the API ML, we would then have /api/v1/servicename/status

A concern is that this might make it difficult to be a client for both cases. Is that valid or is this normal in an API ML?

Context Path Required?

In an old instance of the SDK, there was a context path, so endpoints were something like:
/sampleservice/api/v1/.... Is the guidance to not have this context path in the URI?

OS linkage example - Introduce JNI code

As a developer who is creating an API service, I would like to see an example of the JNI code that is calling MVS code via JNI and OS linkage together with instructions how to build them and run them on z/OS.

The existing code with JNI in the old sample should be migrated to the new sample.

Internationalization (i18n) of REST APIs and REST service

As a developer of the REST API, I would like to know how to do the i18n easily and consistently with other Broadcom products.

  • A way how to define i18n for strings in the code
  • A way how to define i18n for numbered messages (ErrorService)
  • A method of how the required locale is provided to the REST API is defined and propagated the code that is getting the strings or messages, ideally with a little coding
  • A method how the service default locale is defined/configured and used in the threads that are not connected to a REST API request
  • Greeting endpoint is localized
  • Server messages are localized
  • Czech or other localization is provided (for testing purposes)
  • Swagger documentation - defined as a new story - #73

Option to consume SDK via smaller JARs

The current recommendation is that zowe REST API SDK be consumed by importing a single JAR.

While importing one single JAR file may be convenient for some consumers, importing one single JAR file has several disadvantages.

We would like to request that the zowe REST API SDK be able to be consumed in smaller chunks. Instead of a single JAR, we would like the ability to consume only those portions of the SDK which we intend to actively leverage at the present time.

e2e REST API tests against running instance (locally, z/OS)

As a developer of Zowe REST API, I would like to be able to run e2e REST API tests easily against my local instance and against z/OS instance.

Acceptance criteria:

  • Example of appropriate REST integration tests are added (only a test that makes sense to do as an integration test and not as a unit test only)
  • The tests are executed during the CI build (locally on Linux in CircleCI)
  • The REST API integration tests are run against the sample API deployed to z/OS

Relicense Repository - EPL+Apache

As this repository contains sample source code intended to be downloaded and expanded upon, it would be better suited with an EPL+Apache 2.0 dual license.

The OMP Governing Board has approved EPL-2.0 license waivers for sample repositories in Zowe, replaced by the dual license.

To re-license this repository, all contributors should consent by responding to this issue in the affirmative.

Setting messageReason and messageAction

Because I could not find a way to supply optional properties like messageReason and messageAction to the error-handling capabilities supplied by the commons package, I simply have not used them.

Can you confirm if this is true?

Reported by @gejohnston

Switch thread security context for services using PassTickets generated by Zowe Authentication and Authorization Service

As an SDK user, I want to run java code under the same user ID the s user using REST API, so that the code can access mainframe resources only accessible by that user by leveraging future PassTicket support in Zowe to allow me to have a minimum security requirement for my service.

Acceptance Criteria:

  • It is possible to run some Java code under the mainframe security environment for the user that is authenticated to the REST API via Zowe Authentication and Authorization Service
  • This is done by using requiring PassTickets in Zowe and passing them to pthread_security_applid_np() function with function code __CREATE_SECURITY_ENV that requires permission to BPX.SERVER but not to BPX.DAEMON
  • It requires being executed on z/OS, on PC or Mac a dummy implementation can be used

Migrated original story: https://rally1.rallydev.com/#/106710376756d/detail/userstory/288640296608

zowe-api-dev command for i18n and messages

Tooling that simplifies localization and checks its correctness and can generate a message reference for numbered error messages.

  • Create a new zowe-api-dev messages i18n command that will:

    • Create a new localization file - messages_{languageCode}.properties initialized with non-localized and commented text from messages.yml that needs to be localized
    • Checks that existing localization files messages_{languageCode}.properties have all the messages keys covered. This will help developers to find out that a localization is missing for a new message
    • Checks that existing localization does not have any extra keys starting with messages.. To find out extra localization for keys that were removed/renamed in messages.yml
  • New zowe-api-dev messages docgen:

    • Uses @jandadav's docgen approach that generates a Markdown document that can be used in Zowe documentation with a message reference

SafPlatformUser - Valid Username Blank Password

Reporting for another team - SafPlatformUser() does not reject a valid user name with a blank password when called through the SDK basic auth code.

I haven't had a chance to independently verify but capturing here until it is verified.

Cannot Bypass Privacy Error in Chrome for Swagger UI

I'm not sure if there was a change in the repo or in Chrome, but when I attempt to see the swagger UI for a service deployed to z/OS in by browser I now get this error (which I can no longer bypass in Chrome):

image

Has there been some change to cause this?

mount JRUserNotPrivileged

I am toying with zowe samples. While trying out one, I got this error

Mounting zFS filesystem USERID.ZOWE.SAMPLAPI.ZFS to /a/surgo01/zowe-rest-api-sample-spring
Executing z/OS UNIX command '/usr/sbin/mount -v -o aggrgrow -f USERID.ZOWE.SAMPLAPI.ZFS /a/userid/zowe-rest-api-sample-spring'
Error: 
$ FOMF0504I mount error: 8B 119B00B0
USERID.ZOWE.SAMPLAPI.ZFS
EPERM: The operation is not permitted 
JRUserNotPrivileged: The requester of the service is not privileged 

how do i get past this?

java.lang.NullPointerException: null when HTTP protocol is used instead of HTTPS

Steps:

  1. Use http protocol to connect
  2. Following message is displayed:
2019-10-05 15:59:06.400 <ZWEASA1:https-jsse-nio-0.0.0.0-20081-exec-1:33620312> SDKBLD1 (org.apache.coyote.http11.Http11NioProtocol:175) ERROR Error reading request, ignored
java.lang.NullPointerException: null
        at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.getSslSupport(NioEndpoint.java:1392)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1593)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:811)

Expected behavior:

  • No error message and no stack trace in the log

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.