Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Include Page
spaceKeyGrouper
pageTitleNavigation

There is an effort in Grouper v2.6 (unsure of exact build number) to have a OpenAPI/Swagger representation of the Grouper Web Service API.  This a work in progress.

We are using Swagger 1.5.3 (which is OAS 2).  Note the later version did not work as well.

Children Display

Access OpenAPI

There is a demo server static version.  The swagger JSON is here:

https://grouperdemo.internet2.edu/swagger/v4/index.json


Each WS deployment can have has its own Swagger page, put "docs" path after the context after the domain, e.g. http://localhost:8400/grouper-ws/docs

...

ParamSample valueDescription
GROUPER_OPENAPI_TITLEMy institution's group service web servicesTitle at top of swagger page
GROUPER_OPENAPI_BASEURLhttps://server.institution.eduBase URL for WS
GROUPER_OPENAPI_DESCRIPTION_SUFFIXContact OIT to get a credential for the WS.  Pass the user/pass in the HTTP basic auth header.More info in the description of the page

Grouper developer notes: build a new swagger file

Maven compile with swagger:generate the WS which will create a new webapp/docs/index.json file

Code Block
mvn -f grouper-ws/grouper-ws clean compile swagger:generate

[INFO] --- swagger-maven-plugin:3.1.8:generate (default) @ grouper-ws ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

Grouper developer notes: setup the dependencies and pom

Import annotations into WS

Code Block
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.3</version>
        </dependency>

Generate the swagger file on build

Expand
Code Block
            <plugin>
                <groupId>com.github.kongchen</groupId>
                <artifactId>swagger-maven-plugin</artifactId>
                <version>3.1.8</version>
                <configuration>
                    <apiSources>
                      <apiSource>
                            <springmvc>false</springmvc>
                            <locations>edu.internet2.middleware.grouper.ws.rest.GrouperServiceRest</locations>
                            <schemes>https</schemes>
                            <host>grouper.institution.edu</host>
                            <basePath></basePath>
                            <info>
                                <title>Grouper Web Services</title>
                                <version>v2.6.1</version>
                                <description>Grouper Web Service operations.  Substitute vX_Y_AAA with the client version, e.g. v2_6_001.  Note: the base URL and authentication are institution specific.</description>
                            </info>
                            <swaggerDirectory>${basedir}/webapp/docs/</swaggerDirectory>
                            <swaggerFileName>index</swaggerFileName>
                            <attachSwaggerArtifact>true</attachSwaggerArtifact>
                            <outputFormats>json</outputFormats>
                <swaggerDirectory>${basedir}/webapp/docs</swaggerDirectory>
                <attachSwaggerArtifact>true</attachSwaggerArtifact>
                        </apiSource>
                    </apiSources>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
          <!--  plugin>
            <groupId>com.greensopinion.swagger</groupId>
            <artifactId>jaxrs-gen</artifactId>
            <version>1.3.5</version>
            <configuration>
              <apiVersion>1.0</apiVersion>
              <apiBasePath>/api/latest</apiBasePath>
              <packageNames>
                <param>edu.internet2.middleware.grouper.ws</param>
                <param>edu.internet2.middleware.grouper.ws.coresoap</param>
              </packageNames>
              <outputFolder>${basedir}/webapp/docs</outputFolder>
            </configuration>
            <executions>
              <execution>
                <phase>compile</phase>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>
          </plugin -->

Copy the Swagger UI to the WS

swagger-ui-3.52.3\dist → webapp/docs.  Edit the index.html to take out "try now" since authn etc is an issue

Code Block
    const DisableTryItOutPlugin = function() {
      return {
        statePlugins: {
          spec: {
            wrapSelectors: {
              allowTryItOutFor: () => () => false
            }
          }
        }
      }
    }

...

        plugins: [
          SwaggerUIBundle.plugins.DownloadUrl, DisableTryItOutPlugin
        ],

Grouper developer notes: add OpenAPI documentation to a WS operation

...

Code Block
@ApiModel(description = "Request body to find groups")
public class WsRestFindGroupsRequestWrapper {

  private WsRestFindGroupsRequest wsRestFindGroupsRequest;
  
  @ApiModelProperty(name = "WsRestFindGroupsRequest", value = "Identifies the request as a findGroups request")
  public WsRestFindGroupsRequest getWsRestFindGroupsRequest() {
    return wsRestFindGroupsRequest;
  }
  public void setWsRestFindGroupsRequest(WsRestFindGroupsRequest wsRestFindGroupsRequest1) {
    wsRestFindGroupsRequest = wsRestFindGroupsRequest1;
  }
}

...

Code Block
@ApiModel(description = "Response body when a findGroups is successful")
public class WsFindGroupsResultsWrapper {
  private WsFindGroupsResults wsFindGroupsResults;

  @ApiModelProperty(name = "WsFindGroupsResults", value = "Identifies the response for findGroups")
  public WsFindGroupsResults getWsFindGroupsResults() {
    return wsFindGroupsResults;
  }
  public void setWsFindGroupsResults(WsFindGroupsResults wsFindGroupsResults) {
    this.wsFindGroupsResults = wsFindGroupsResults;
  }
}

...

Code Block
@ApiModel(description = "Response body when not successful contains error message and metadata")
public class WsFindGroupsResultsWrapperError {
  private WsResultsError wsFindGroupsResults;

  @ApiModelProperty(name = "WsFindGroupsResults", value = "Identifies the response for findGroups")
  public WsResultsError getWsFindGroupsResults() {
    return wsFindGroupsResults;
  }
  public void setWsFindGroupsResults(WsResultsError wsFindGroupsResults1) {
    this.wsFindGroupsResults = wsFindGroupsResults1;
  }
}

...

Code Block
  @POST
  @Path("/grouper-ws/servicesRest/vX_Y_0ZA/groups")   @ApiOperation(httpMethod = "POST", value = "Find groups", nickname = "findGroups", response = WsFindGroupsResultsWrapper.class,
      notes = "<b>Sample 1</b>: Find by substring in a folder<br /><pre>POST /grouper-ws/servicesRest/v2_6_001/groups<br />"
          + "{<br>  "WsRestFindGroupsRequest":{<br>    "wsQueryFilter":{<br>      "queryFilterType":"FIND_BY_GROUP_NAME_APPROXIMATE",<br>      "stemName":"aStem",<br>      "groupName":"aGr"<br>    }<br>  }<br>}</pre>") 
  @ApiResponses({@ApiResponse(code = 200, message = "SUCCESS", response = WsFindGroupsResultsWrapper.class),
                @ApiResponse(code = 400, message = "INVALID_QUERY", response = WsFindGroupsResultsWrapperError.class),
                @ApiResponse(code = 404, message = "STEM_NOT_FOUND", response = WsFindGroupsResultsWrapperError.class),
                @ApiResponse(code = 500, message = "EXCEPTION", response = WsFindGroupsResultsWrapperError.class)})
  @ApiImplicitParams({
    @ApiImplicitParam(required = true, dataType = "edu.internet2.middleware.grouper.ws.rest.group.WsRestFindGroupsRequestWrapper", paramType = "body")})
  public static WsFindGroupsResults findGroups(GrouperVersion clientVersion,

...

Code Block
@ApiModel(description = "Request body to find groups")
public class WsRestFindGroupsRequestWrapper {

...

Code Block
  @ApiModelProperty(value = "Integer ID for object", example = "12345")
  public String getIdIndex() {

...