From 0375976c91529734efc2272b947e1a330d25bac7 Mon Sep 17 00:00:00 2001 From: Aman Kapoor Date: Tue, 23 Sep 2025 02:13:00 +0530 Subject: [PATCH] Added Java reference implementation Signed-off-by: Aman Kapoor --- fdc3-appd-reference-Impl-java/README.md | 79 ++ .../fdc3-app-directory-java/.gitattributes | 2 + .../fdc3-app-directory-java/.gitignore | 33 + .../.mvn/wrapper/maven-wrapper.properties | 19 + .../fdc3-app-directory-java/pom.xml | 225 +++ .../src/main/java/com/fdc/appd/ApiUtil.java | 20 + ...Fdc3AppDirectoryJavaSpringApplication.java | 21 + .../src/main/java/com/fdc/appd/V1Api.java | 195 +++ .../java/com/fdc/appd/V1ApiController.java | 27 + .../main/java/com/fdc/appd/V1ApiDelegate.java | 163 +++ .../src/main/java/com/fdc/appd/V2Api.java | 130 ++ .../java/com/fdc/appd/V2ApiController.java | 27 + .../main/java/com/fdc/appd/V2ApiDelegate.java | 47 + .../java/com/fdc/appd/V2ApiDelegateImpl.java | 73 + .../datasources/JsonDatasourceConfig.java | 25 + .../appd/model/AllApplicationsResponse.java | 111 ++ .../java/com/fdc/appd/model/AppImageV1.java | 78 + .../java/com/fdc/appd/model/Application.java | 619 ++++++++ .../model/ApplicationSearchResponseV1.java | 111 ++ .../com/fdc/appd/model/ApplicationV1.java | 467 ++++++ .../com/fdc/appd/model/BaseApplication.java | 556 ++++++++ .../com/fdc/appd/model/CitrixAppDetails.java | 112 ++ .../java/com/fdc/appd/model/ErrorDTO.java | 99 ++ .../fdc/appd/model/HostManifestsValue.java | 9 + .../main/java/com/fdc/appd/model/Icon.java | 126 ++ .../main/java/com/fdc/appd/model/IconV1.java | 78 + .../main/java/com/fdc/appd/model/Intent.java | 172 +++ .../java/com/fdc/appd/model/IntentV1.java | 172 +++ .../main/java/com/fdc/appd/model/Interop.java | 136 ++ .../appd/model/InteropAppChannelsInner.java | 182 +++ .../com/fdc/appd/model/InteropIntents.java | 123 ++ .../fdc/appd/model/InteropUserChannels.java | 123 ++ .../com/fdc/appd/model/LaunchDetails.java | 9 + .../com/fdc/appd/model/NameValuePair.java | 100 ++ .../com/fdc/appd/model/NativeAppDetails.java | 112 ++ .../appd/model/OnlineNativeAppDetails.java | 90 ++ .../java/com/fdc/appd/model/Screenshot.java | 150 ++ .../main/java/com/fdc/appd/model/Type.java | 50 + .../com/fdc/appd/model/WebAppDetails.java | 88 ++ .../fdc/appd/security/JwtAuthInterceptor.java | 41 + .../java/com/fdc/appd/security/JwtUtil.java | 42 + .../appd/security/UserManagementService.java | 8 + .../security/UserManagementServiceImpl.java | 40 + .../java/com/fdc/appd/security/WebConfig.java | 18 + .../service/ApplicationReaderFactory.java | 32 + .../service/V2ApplicationJsonReaderImpl.java | 87 ++ .../fdc/appd/service/V2ApplicationReader.java | 27 + .../resources/app-directory-schema-2.0.yml | 1255 +++++++++++++++++ .../src/main/resources/application.properties | 7 + .../src/main/resources/local.v2.json | 871 ++++++++++++ .../src/main/resources/user_db.json | 5 + ...ppDirectoryJavaSpringApplicationTests.java | 10 + .../com/fdc/appd/V2ApiDelegateImplTests.java | 126 ++ .../service/ApplicationReaderFactoryTest.java | 45 + .../V2ApplicationJsonReaderImplTest.java | 67 + .../src/test/resources/test.local.v2.json | 220 +++ 56 files changed, 7860 insertions(+) create mode 100755 fdc3-appd-reference-Impl-java/README.md create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitattributes create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitignore create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.mvn/wrapper/maven-wrapper.properties create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/pom.xml create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/ApiUtil.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplication.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1Api.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiController.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiDelegate.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2Api.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiController.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegate.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegateImpl.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/datasources/JsonDatasourceConfig.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AllApplicationsResponse.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AppImageV1.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Application.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationSearchResponseV1.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationV1.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/BaseApplication.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/CitrixAppDetails.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ErrorDTO.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/HostManifestsValue.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Icon.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IconV1.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Intent.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IntentV1.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Interop.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropAppChannelsInner.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropIntents.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropUserChannels.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/LaunchDetails.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NameValuePair.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NativeAppDetails.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/OnlineNativeAppDetails.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Screenshot.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Type.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/WebAppDetails.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtAuthInterceptor.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtUtil.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementService.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementServiceImpl.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/WebConfig.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/ApplicationReaderFactory.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationJsonReaderImpl.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationReader.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/app-directory-schema-2.0.yml create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/application.properties create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/local.v2.json create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/user_db.json create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplicationTests.java create mode 100644 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/V2ApiDelegateImplTests.java create mode 100644 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/ApplicationReaderFactoryTest.java create mode 100644 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/V2ApplicationJsonReaderImplTest.java create mode 100755 fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/resources/test.local.v2.json diff --git a/fdc3-appd-reference-Impl-java/README.md b/fdc3-appd-reference-Impl-java/README.md new file mode 100755 index 00000000..21af7c0a --- /dev/null +++ b/fdc3-appd-reference-Impl-java/README.md @@ -0,0 +1,79 @@ +# FDC3 APP Directory Reference Implementation - Java + Springboot + +An application directory (appD) is a structured repository of information about apps that can be used in an FDC3-enabled desktop(more info [here](https://fdc3.finos.org)). In other words, it’s a convenient way of storing and managing metadata about apps in your ecosystem. + +The application metadata stored in appD records may include: the app name, type, details about how to run the application, its icons, publisher, support contact details and so on. It may also include links to or embed manifest formats defined elsewhere, such as proprietary manifests for launching the app in a container product or a Web Application Manifest (as defined by the W3C). + +All this information is readily available in one place and can be used both to populate a launcher or app catalog UI for your users, and by the Desktop Agent managing the apps on your desktop. In fact, if your desktop platform supports the FDC3 standard, appD is the primary way that the FDC3 Desktop Agent implementation should receive the details about apps available to run on your desktop. Conversely, if an app is not listed in appD, the Desktop Agent can’t ensure its participation in context sharing or use it to resolve intents. + +## Foreword + +This is a reference implementation for app Directory implemented in Java and springboot. + +The implementation is packaged with a sample App Directory JSON (src/main/resources/local.v2.json) to demo the functional APIs out of he bix We have also configured a sample user base to demo the authorization and authentication. The details for exeuting the API end points are given below. + + +## Try out on local machine + +> Note : Required Java Version 17+. + +1. Clone the repository to your local machine + +> mkdir FDC3 +> +> cd FDC3 +> +> git clone https://github.com/amanjmd/FINOS.git +> + +2. Install the Dependencies + +> cd FINOS/fdc3-app-directory-java +> +> mvn clean install + +3. Run the application + +>java -jar target/*.jar +> + +# Test the application +>curl --location 'http://localhost:8080/v2/apps' \ +> +>--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWxpY2UifQ.2cfycMS2ZZlROOrhG23Dz8fxnq2AnW4dspC3agP2MMo' \ +> +>--data '' + + +### API End points implemented +1. /v2/apps +2. /v2/apps/{appId} + + +# Key Demos + +## Support for multiple Datasources +This is implementation by default implementation for the JSON datasource . +It can be further extended using the "V2ApplicationReader" to provide the custom implementation for other datasources like releational , NoSQL etc. + +## Support for authentication/ authorization + +This implementaiton further includes a simpler implementation of authentication and authorization . Here in , there are 2 valid users "alice", "bob" (user_db.json). + +To run this application in local , we would require the JWT tokens . Below are the tokens for Alice and Bob , which needs to be sent in "Authorization" header. + +> Alice : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoicG9ydGZvbGlvLW1hbmFnZXIifQ.iJk3t2bUjWQJ-CNaJ4dzzJ5AQfcjpb8oxq0epX9G8cg +> +> Bob : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYm9iIiwicm9sZSI6ImVxdWl0eS1zZWxsLXRyYWRlciJ9.NLfQbFWUrOtiHEe_FpMsB3TK-DtJgLJdBrHwVNGbbIw +> +> Key to generate token : mIU3RoraRfc8TF3ScboaF8lcQF0nb5gb +> +> +Note : In the enterprise implementation , there would be an IAM services in place to generate the token.Hence the UserManagementService can be modified accordingly. + + + + + + + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitattributes b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitattributes new file mode 100755 index 00000000..3b41682a --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitignore b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitignore new file mode 100755 index 00000000..549e00a2 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.mvn/wrapper/maven-wrapper.properties b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 00000000..d58dfb70 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/pom.xml b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/pom.xml new file mode 100755 index 00000000..3b45c07f --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/pom.xml @@ -0,0 +1,225 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.0-SNAPSHOT + + + com.fdc + appd + 0.0.1-SNAPSHOT + fdc3-app-directory-java-spring + Java Spring boot implementation for App Directory with FDC3 Specs + + + + + + + + + + + + + + + 17 + + + + + commons-codec + commons-codec + 1.15 + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + org.springframework.boot + spring-boot-starter-web + + + io.springfox + springfox-boot-starter + 3.0.0 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.swagger.core.v3 + swagger-annotations + 2.2.25 + + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + javax.validation + validation-api + 2.0.1.Final + + + + jakarta.validation + jakarta.validation-api + 3.0.0 + + + + org.openapitools + jackson-databind-nullable + 0.2.6 + + + + javax.annotation + javax.annotation-api + 1.3.2 + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + com.fasterxml.jackson.core + jackson-databind + 2.18.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + false + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + false + + + + + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/ApiUtil.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/ApiUtil.java new file mode 100755 index 00000000..758e2c09 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/ApiUtil.java @@ -0,0 +1,20 @@ +package com.fdc.appd; + + +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiUtil { + public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { + try { + HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); + res.setCharacterEncoding("UTF-8"); + res.addHeader("Content-Type", contentType); + res.getWriter().print(example); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplication.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplication.java new file mode 100755 index 00000000..52cdf622 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplication.java @@ -0,0 +1,21 @@ +package com.fdc.appd; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; + +@SpringBootApplication(exclude = { + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class, + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +public class Fdc3AppDirectoryJavaSpringApplication { + + public static void main(String[] args) { + SpringApplication.run(Fdc3AppDirectoryJavaSpringApplication.class, args); + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1Api.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1Api.java new file mode 100755 index 00000000..71477b44 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1Api.java @@ -0,0 +1,195 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.8.0). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package com.fdc.appd; + +import com.fdc.appd.model.ApplicationSearchResponseV1; +import com.fdc.appd.model.ApplicationV1; +import com.fdc.appd.model.ErrorDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +@Validated +@Tag(name = "Application", description = "the Application API") +public interface V1Api { + + default V1ApiDelegate getDelegate() { + return new V1ApiDelegate() {}; + } + + /** + * GET /v1/apps/{appId} : Retrieve an application definition + * + * @param appId (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + */ + @Deprecated + @Operation( + operationId = "v1AppsAppIdGet", + summary = "Retrieve an application definition", + deprecated = true, + tags = { "Application" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationV1.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ApplicationV1.class)) + }), + @ApiResponse(responseCode = "400", description = "Bad request.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "403", description = "Forbidden: Certificate authentication is not allowed for the requested user.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "500", description = "Server error, see response body for further details.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }) + }, + security = { + @SecurityRequirement(name = "bearerAuth") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/v1/apps/{appId}", + produces = { "application/json", "*/*" } + ) + + default ResponseEntity v1AppsAppIdGet( + @Parameter(name = "appId", description = "", required = true, in = ParameterIn.PATH) @PathVariable("appId") String appId + ) { + return getDelegate().v1AppsAppIdGet(appId); + } + + + /** + * POST /v1/apps : Create a new application definition + * + * @param applicationV1 (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + */ + @Deprecated + @Operation( + operationId = "v1AppsPost", + summary = "Create a new application definition", + deprecated = true, + tags = { "Application" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationSearchResponseV1.class)) + }), + @ApiResponse(responseCode = "400", description = "Bad request.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "403", description = "Forbidden: Certificate authentication is not allowed for the requested user.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "500", description = "Server error, see response body for further details.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }) + }, + security = { + @SecurityRequirement(name = "bearerAuth") + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/apps", + produces = { "application/json" }, + consumes = { "application/json" } + ) + + default ResponseEntity v1AppsPost( + @Parameter(name = "ApplicationV1", description = "", required = true) @Valid @RequestBody ApplicationV1 applicationV1 + ) { + return getDelegate().v1AppsPost(applicationV1); + } + + + /** + * GET /v1/apps/search : Retrieve a list of applications based on parameters provided. Depending on implementation, parameter values should self describe search format and type (e.g. Regex) + * + * @param appId The unique application identifier located within a specific application directory instance. (optional) + * @param name The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. (optional) + * @param version Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA) (optional) + * @param title Optional title for the application, if missing use appName, typically used in a launcher UI. (optional) + * @param tooltip Optional tooltip description e.g. for a launcher (optional) + * @param description Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language (optional) + * @param intentName name of intent (optional) + * @param intentDisplayName displayName of intent (optional) + * @param intentContext search contexts list (optional) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + */ + @Deprecated + @Operation( + operationId = "v1AppsSearchGet", + summary = "Retrieve a list of applications based on parameters provided. Depending on implementation, parameter values should self describe search format and type (e.g. Regex)", + deprecated = true, + tags = { "Application" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationSearchResponseV1.class)) + }), + @ApiResponse(responseCode = "400", description = "Bad request.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "403", description = "Forbidden: Certificate authentication is not allowed for the requested user.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "500", description = "Server error, see response body for further details.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)) + }) + }, + security = { + @SecurityRequirement(name = "bearerAuth") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/v1/apps/search", + produces = { "application/json" } + ) + + default ResponseEntity v1AppsSearchGet( + @Parameter(name = "appId", description = "The unique application identifier located within a specific application directory instance. ", in = ParameterIn.QUERY) @Valid @RequestParam(value = "appId", required = false) String appId, + @Parameter(name = "name", description = "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. ", in = ParameterIn.QUERY) @Valid @RequestParam(value = "name", required = false) String name, + @Parameter(name = "version", description = "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)", in = ParameterIn.QUERY) @Valid @RequestParam(value = "version", required = false) String version, + @Parameter(name = "title", description = "Optional title for the application, if missing use appName, typically used in a launcher UI.", in = ParameterIn.QUERY) @Valid @RequestParam(value = "title", required = false) String title, + @Parameter(name = "tooltip", description = "Optional tooltip description e.g. for a launcher", in = ParameterIn.QUERY) @Valid @RequestParam(value = "tooltip", required = false) String tooltip, + @Parameter(name = "description", description = "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language", in = ParameterIn.QUERY) @Valid @RequestParam(value = "description", required = false) String description, + @Parameter(name = "intent_name", description = "name of intent", in = ParameterIn.QUERY) @Valid @RequestParam(value = "intent_name", required = false) String intentName, + @Parameter(name = "intent_displayName", description = "displayName of intent", in = ParameterIn.QUERY) @Valid @RequestParam(value = "intent_displayName", required = false) String intentDisplayName, + @Parameter(name = "intent_context", description = "search contexts list", in = ParameterIn.QUERY) @Valid @RequestParam(value = "intent_context", required = false) String intentContext + ) { + return getDelegate().v1AppsSearchGet(appId, name, version, title, tooltip, description, intentName, intentDisplayName, intentContext); + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiController.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiController.java new file mode 100755 index 00000000..39895e48 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiController.java @@ -0,0 +1,27 @@ +package com.fdc.appd; + + +import jakarta.annotation.Generated; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.Optional; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +@Controller +@RequestMapping("${openapi.fDC3ApplicationDirectory.base-path:/appd}") +public class V1ApiController implements V1Api { + + private final V1ApiDelegate delegate; + + public V1ApiController(@Autowired(required = false) V1ApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).orElse(new V1ApiDelegate() {}); + } + + @Override + public V1ApiDelegate getDelegate() { + return delegate; + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiDelegate.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiDelegate.java new file mode 100755 index 00000000..86588350 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V1ApiDelegate.java @@ -0,0 +1,163 @@ +package com.fdc.appd; + +import com.fdc.appd.model.ApplicationSearchResponseV1; +import com.fdc.appd.model.ApplicationV1; +import jakarta.annotation.Generated; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.context.request.NativeWebRequest; + +import java.util.Optional; + +/** + * A delegate to be called by the {@link V1ApiController}}. + * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. + */ +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public interface V1ApiDelegate { + + default Optional getRequest() { + return Optional.empty(); + } + + /** + * GET /v1/apps/{appId} : Retrieve an application definition + * + * @param appId (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + * @see V1Api#v1AppsAppIdGet + */ + @Deprecated + default ResponseEntity v1AppsAppIdGet(String appId) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"images\" : [ { \"url\" : \"https://openapi-generator.tech\" }, { \"url\" : \"https://openapi-generator.tech\" } ], \"intents\" : [ { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] }, { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] } ], \"contactEmail\" : \"contactEmail\", \"manifest\" : \"manifest\", \"tooltip\" : \"tooltip\", \"manifestType\" : \"manifestType\", \"description\" : \"description\", \"title\" : \"title\", \"icons\" : [ { \"icon\" : \"https://openapi-generator.tech\" }, { \"icon\" : \"https://openapi-generator.tech\" } ], \"version\" : \"version\", \"supportEmail\" : \"supportEmail\", \"customConfig\" : [ { \"name\" : \"name\", \"value\" : \"value\" }, { \"name\" : \"name\", \"value\" : \"value\" } ], \"appId\" : \"appId\", \"name\" : \"name\", \"publisher\" : \"publisher\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + /** + * POST /v1/apps : Create a new application definition + * + * @param applicationV1 (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + * @see V1Api#v1AppsPost + */ + @Deprecated + default ResponseEntity v1AppsPost(ApplicationV1 applicationV1) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"message\" : \"message\", \"applications\" : [ { \"images\" : [ { \"url\" : \"https://openapi-generator.tech\" }, { \"url\" : \"https://openapi-generator.tech\" } ], \"intents\" : [ { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] }, { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] } ], \"contactEmail\" : \"contactEmail\", \"manifest\" : \"manifest\", \"tooltip\" : \"tooltip\", \"manifestType\" : \"manifestType\", \"description\" : \"description\", \"title\" : \"title\", \"icons\" : [ { \"icon\" : \"https://openapi-generator.tech\" }, { \"icon\" : \"https://openapi-generator.tech\" } ], \"version\" : \"version\", \"supportEmail\" : \"supportEmail\", \"customConfig\" : [ { \"name\" : \"name\", \"value\" : \"value\" }, { \"name\" : \"name\", \"value\" : \"value\" } ], \"appId\" : \"appId\", \"name\" : \"name\", \"publisher\" : \"publisher\" }, { \"images\" : [ { \"url\" : \"https://openapi-generator.tech\" }, { \"url\" : \"https://openapi-generator.tech\" } ], \"intents\" : [ { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] }, { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] } ], \"contactEmail\" : \"contactEmail\", \"manifest\" : \"manifest\", \"tooltip\" : \"tooltip\", \"manifestType\" : \"manifestType\", \"description\" : \"description\", \"title\" : \"title\", \"icons\" : [ { \"icon\" : \"https://openapi-generator.tech\" }, { \"icon\" : \"https://openapi-generator.tech\" } ], \"version\" : \"version\", \"supportEmail\" : \"supportEmail\", \"customConfig\" : [ { \"name\" : \"name\", \"value\" : \"value\" }, { \"name\" : \"name\", \"value\" : \"value\" } ], \"appId\" : \"appId\", \"name\" : \"name\", \"publisher\" : \"publisher\" } ] }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + /** + * GET /v1/apps/search : Retrieve a list of applications based on parameters provided. Depending on implementation, parameter values should self describe search format and type (e.g. Regex) + * + * @param appId The unique application identifier located within a specific application directory instance. (optional) + * @param name The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. (optional) + * @param version Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA) (optional) + * @param title Optional title for the application, if missing use appName, typically used in a launcher UI. (optional) + * @param tooltip Optional tooltip description e.g. for a launcher (optional) + * @param description Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language (optional) + * @param intentName name of intent (optional) + * @param intentDisplayName displayName of intent (optional) + * @param intentContext search contexts list (optional) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @deprecated + * @see V1Api#v1AppsSearchGet + */ + @Deprecated + default ResponseEntity v1AppsSearchGet(String appId, + String name, + String version, + String title, + String tooltip, + String description, + String intentName, + String intentDisplayName, + String intentContext) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"message\" : \"message\", \"applications\" : [ { \"images\" : [ { \"url\" : \"https://openapi-generator.tech\" }, { \"url\" : \"https://openapi-generator.tech\" } ], \"intents\" : [ { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] }, { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] } ], \"contactEmail\" : \"contactEmail\", \"manifest\" : \"manifest\", \"tooltip\" : \"tooltip\", \"manifestType\" : \"manifestType\", \"description\" : \"description\", \"title\" : \"title\", \"icons\" : [ { \"icon\" : \"https://openapi-generator.tech\" }, { \"icon\" : \"https://openapi-generator.tech\" } ], \"version\" : \"version\", \"supportEmail\" : \"supportEmail\", \"customConfig\" : [ { \"name\" : \"name\", \"value\" : \"value\" }, { \"name\" : \"name\", \"value\" : \"value\" } ], \"appId\" : \"appId\", \"name\" : \"name\", \"publisher\" : \"publisher\" }, { \"images\" : [ { \"url\" : \"https://openapi-generator.tech\" }, { \"url\" : \"https://openapi-generator.tech\" } ], \"intents\" : [ { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] }, { \"customConfig\" : \"{}\", \"displayName\" : \"displayName\", \"name\" : \"name\", \"contexts\" : [ \"contexts\", \"contexts\" ] } ], \"contactEmail\" : \"contactEmail\", \"manifest\" : \"manifest\", \"tooltip\" : \"tooltip\", \"manifestType\" : \"manifestType\", \"description\" : \"description\", \"title\" : \"title\", \"icons\" : [ { \"icon\" : \"https://openapi-generator.tech\" }, { \"icon\" : \"https://openapi-generator.tech\" } ], \"version\" : \"version\", \"supportEmail\" : \"supportEmail\", \"customConfig\" : [ { \"name\" : \"name\", \"value\" : \"value\" }, { \"name\" : \"name\", \"value\" : \"value\" } ], \"appId\" : \"appId\", \"name\" : \"name\", \"publisher\" : \"publisher\" } ] }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = "{ \"code\" : 0, \"message\" : \"message\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2Api.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2Api.java new file mode 100755 index 00000000..d20b6891 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2Api.java @@ -0,0 +1,130 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.8.0). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package com.fdc.appd; + +import com.fdc.appd.model.AllApplicationsResponse; +import com.fdc.appd.model.Application; +import com.fdc.appd.model.ErrorDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Generated; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +@Validated +@Tag(name = "Application", description = "the Application API") +public interface V2Api { + + default V2ApiDelegate getDelegate() { + return new V2ApiDelegate() {}; + } + + /** + * GET /v2/apps/{appId} : Retrieve an application definition + * + * @param appId (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + */ + @Operation( + operationId = "v2AppsAppIdGet", + summary = "Retrieve an application definition", + tags = { "Application" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = Application.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = Application.class)) + }), + @ApiResponse(responseCode = "400", description = "Bad request.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "403", description = "Forbidden: Certificate authentication is not allowed for the requested user.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "500", description = "Server error, see response body for further details.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }) + }, + security = { + @SecurityRequirement(name = "bearerAuth") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/v2/apps/{appId}", + produces = { "application/json", "*/*" } + ) + + default ResponseEntity v2AppsAppIdGet(@RequestHeader(name="Authorization") String token, + @Parameter(name = "appId", description = "", required = true, in = ParameterIn.PATH) @PathVariable("appId") String appId + ) { + return getDelegate().v2AppsAppIdGet(appId,token); + } + + + /** + * GET /v2/apps : Retrieve all application definitions + * + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + */ + @Operation( + operationId = "v2AppsGet", + summary = "Retrieve all application definitions", + tags = { "Application" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = AllApplicationsResponse.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = AllApplicationsResponse.class)) + }), + @ApiResponse(responseCode = "400", description = "Bad request.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "403", description = "Forbidden: Certificate authentication is not allowed for the requested user.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }), + @ApiResponse(responseCode = "500", description = "Server error, see response body for further details.", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorDTO.class)), + @Content(mediaType = "*/*", schema = @Schema(implementation = ErrorDTO.class)) + }) + }, + security = { + @SecurityRequirement(name = "bearerAuth") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/v2/apps", + produces = { "application/json", "*/*" } + ) + + default ResponseEntity v2AppsGet(@RequestHeader(name="Authorization") String token + + ) { + return getDelegate().v2AppsGet(token); + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiController.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiController.java new file mode 100755 index 00000000..ab6941f9 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiController.java @@ -0,0 +1,27 @@ +package com.fdc.appd; + + +import jakarta.annotation.Generated; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Optional; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +@RestController +@RequestMapping("${openapi.fDC3ApplicationDirectory.base-path:/}") +public class V2ApiController implements V2Api { + + private final V2ApiDelegate delegate; + + public V2ApiController(@Autowired(required = false) V2ApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).get(); + } + + @Override + public V2ApiDelegate getDelegate() { + return delegate; + } + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegate.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegate.java new file mode 100755 index 00000000..a6b27960 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegate.java @@ -0,0 +1,47 @@ +package com.fdc.appd; + +import com.fdc.appd.model.AllApplicationsResponse; +import com.fdc.appd.model.Application; +import jakarta.annotation.Generated; +import org.springframework.http.ResponseEntity; + +/** + * A delegate to be called by the {@link V2ApiController}}. + * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. + */ +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public interface V2ApiDelegate { + + + + + /** + * GET /v2/apps/{appId} : Retrieve an application definition + * + * @param appId (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @see V2Api#v2AppsAppIdGet + */ + default public ResponseEntity v2AppsAppIdGet(String appId, String authHeader){ + return ResponseEntity.internalServerError().build(); + } ; + + + + /** + * GET /v2/apps : Retrieve all application definitions + * + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @see V2Api#v2AppsGet + */ + default public ResponseEntity v2AppsGet( String authHeader){ + return ResponseEntity.internalServerError().build(); + } ; + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegateImpl.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegateImpl.java new file mode 100755 index 00000000..7f973452 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/V2ApiDelegateImpl.java @@ -0,0 +1,73 @@ +package com.fdc.appd; + +import com.fdc.appd.model.AllApplicationsResponse; +import com.fdc.appd.model.Application; +import com.fdc.appd.security.JwtUtil; +import com.fdc.appd.security.UserManagementService; +import com.fdc.appd.service.ApplicationReaderFactory; +import com.fdc.appd.service.V2ApplicationReader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class V2ApiDelegateImpl implements V2ApiDelegate{ + + + @Autowired + UserManagementService userManagementService; + + + @Autowired + ApplicationReaderFactory readerFactory; + + + /** + * GET /v2/apps/{appId} : Retrieve an application definition + * + * @param appId (required) + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @see V2Api#v2AppsAppIdGet + */ + @Override + public ResponseEntity v2AppsAppIdGet(String appId, String authHeader) { + if(!userManagementService.validateUser(JwtUtil.getUser(authHeader))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + V2ApplicationReader applicationReader = readerFactory.createApplicationReader(); + try { + return ResponseEntity.ok(applicationReader.getApplication(appId)); + } catch (IOException|RuntimeException e) { + throw new RuntimeException(e); + } + } + + /** + * GET /v2/apps : Retrieve all application definitions + * + * @return OK (status code 200) + * or Bad request. (status code 400) + * or Forbidden: Certificate authentication is not allowed for the requested user. (status code 403) + * or Server error, see response body for further details. (status code 500) + * @see V2Api#v2AppsGet + */ + @Override + public ResponseEntity v2AppsGet(String authHeader) { + if(!userManagementService.validateUser(JwtUtil.getUser(authHeader))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); + V2ApplicationReader applicationReader = readerFactory.createApplicationReader(); + try { + AllApplicationsResponse allApplication = applicationReader.getAllApplication(); + allApplication.setMessage("Ok"); + ResponseEntity ok = ResponseEntity.ok(allApplication); + return ok; + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/datasources/JsonDatasourceConfig.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/datasources/JsonDatasourceConfig.java new file mode 100755 index 00000000..0abf3fb5 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/datasources/JsonDatasourceConfig.java @@ -0,0 +1,25 @@ +package com.fdc.appd.datasources; + + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + + +/** + * This is the main configuration holder for the application details JSON file . + * The value should be included in the application properties. + */ +@Component +@ConfigurationProperties("fdc.appd.app-json") +public class JsonDatasourceConfig { + + public String path ; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AllApplicationsResponse.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AllApplicationsResponse.java new file mode 100755 index 00000000..615e8df1 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AllApplicationsResponse.java @@ -0,0 +1,111 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * AllApplicationsResponse + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class AllApplicationsResponse { + + @Valid + private List applications = new ArrayList<>(); + + private String message; + + public AllApplicationsResponse applications(List applications) { + this.applications = applications; + return this; + } + + public AllApplicationsResponse addApplicationsItem(Application applicationsItem) { + if (this.applications == null) { + this.applications = new ArrayList<>(); + } + this.applications.add(applicationsItem); + return this; + } + + /** + * List of applications + * @return applications + */ + @Valid + @Schema(name = "applications", description = "List of applications ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("applications") + public List getApplications() { + return applications; + } + + public void setApplications(List applications) { + this.applications = applications; + } + + public AllApplicationsResponse message(String message) { + this.message = message; + return this; + } + + /** + * Response message providing status of query + * @return message + */ + + @Schema(name = "message", description = "Response message providing status of query ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AllApplicationsResponse allApplicationsResponse = (AllApplicationsResponse) o; + return Objects.equals(this.applications, allApplicationsResponse.applications) && + Objects.equals(this.message, allApplicationsResponse.message); + } + + @Override + public int hashCode() { + return Objects.hash(applications, message); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AllApplicationsResponse {\n"); + sb.append(" applications: ").append(toIndentedString(applications)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AppImageV1.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AppImageV1.java new file mode 100755 index 00000000..8a70432c --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/AppImageV1.java @@ -0,0 +1,78 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.net.URI; +import java.util.Objects; + +/** + * App Image holder + */ + +@Schema(name = "AppImageV1", description = "App Image holder") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class AppImageV1 { + + private URI url; + + public AppImageV1 url(URI url) { + this.url = url; + return this; + } + + /** + * App Image URL + * @return url + */ + @Valid + @Schema(name = "url", description = "App Image URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("url") + public URI getUrl() { + return url; + } + + public void setUrl(URI url) { + this.url = url; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AppImageV1 appImageV1 = (AppImageV1) o; + return Objects.equals(this.url, appImageV1.url); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AppImageV1 {\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Application.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Application.java new file mode 100755 index 00000000..83884601 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Application.java @@ -0,0 +1,619 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +//import jakarta.persistence.Column; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +import java.net.URI; +import java.util.*; + +/** + * Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec. + */ + +@Schema(name = "Application", description = "Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec. ") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") + +public class Application { + + + private String appId; + + + private String name; + + + private Type type; + + + private Map details; + + + private String version; + + + private String title; + + + private String tooltip; + + + private String lang; + + + private String description; + + @Valid + private List categories = new ArrayList<>(); + + @Valid + private List<@Valid Icon> icons = new ArrayList<>(); + + @Valid + private List<@Valid Screenshot> screenshots = new ArrayList<>(); + + + private String contactEmail; + + + private String supportEmail; + + private URI moreInfo; + + + private String publisher; + + @Valid + private List<@Valid NameValuePair> customConfig = new ArrayList<>(); + + @Valid + private Map hostManifests = new HashMap<>(); + + private Interop interop; + + @Valid + private Map localizedVersions = new HashMap<>(); + + public Application() { + super(); + } + + /** + * Constructor with only required parameters + */ + public Application(String appId, String name, Type type, Map details) { + this.appId = appId; + this.name = name; + this.type = type; + this.details = details; + } + + public Application appId(String appId) { + this.appId = appId; + return this; + } + + /** + * The unique application identifier located within a specific application directory instance. + * @return appId + */ + @NotNull + @Schema(name = "appId", description = "The unique application identifier located within a specific application directory instance. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("appId") + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public Application name(String name) { + this.name = name; + return this; + } + + /** + * The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. + * @return name + */ + @NotNull + @Schema(name = "name", description = "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Application type(Type type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @NotNull @Valid + @Schema(name = "type", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("type") + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public Application details(Map details) { + this.details = details; + return this; + } + + /** + * Get details + * @return details + */ + @NotNull @Valid + @Schema(name = "details", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("details") + public Map getDetails() { + return details; + } + + public void setDetails(Map details) { + this.details = details; + } + + public Application version(String version) { + this.version = version; + return this; + } + + /** + * Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA) + * @return version + */ + + @Schema(name = "version", description = "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("version") + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Application title(String title) { + this.title = title; + return this; + } + + /** + * Optional title for the application, if missing use appName, typically used in a launcher UI. + * @return title + */ + + @Schema(name = "title", description = "Optional title for the application, if missing use appName, typically used in a launcher UI.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("title") + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Application tooltip(String tooltip) { + this.tooltip = tooltip; + return this; + } + + /** + * Optional tooltip description e.g. for a launcher + * @return tooltip + */ + + @Schema(name = "tooltip", description = "Optional tooltip description e.g. for a launcher", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tooltip") + public String getTooltip() { + return tooltip; + } + + public void setTooltip(String tooltip) { + this.tooltip = tooltip; + } + + public Application lang(String lang) { + this.lang = lang; + return this; + } + + /** + * A language tag that specifies the primary language of both the application and its AppD entry, as defined by IETF RFC 5646. + * @return lang + */ + @Pattern(regexp = "^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$") + @Schema(name = "lang", description = "A language tag that specifies the primary language of both the application and its AppD entry, as defined by IETF RFC 5646.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("lang") + public String getLang() { + return lang; + } + + public void setLang(String lang) { + this.lang = lang; + } + + public Application description(String description) { + this.description = description; + return this; + } + + /** + * Description of the application. This will typically be a 1-2 paragraph style blurb about the application. + * @return description + */ + + @Schema(name = "description", description = "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Application categories(List categories) { + this.categories = categories; + return this; + } + + public Application addCategoriesItem(String categoriesItem) { + if (this.categories == null) { + this.categories = new ArrayList<>(); + } + this.categories.add(categoriesItem); + return this; + } + + /** + * An array of string categories that describe the application. These are meant as a hint to catalogs or stores listing FDC3-enabled apps and it is expected that these will make a best effort to find appropriate categories (or category) under which to list the app. AppD record authors are encouraged to use lower-case and, where possible, to select categories from the following list: - allocations - analytics - charts - chat - communication - compliance - crm - developer tools - events - execution management - file sharing - market data - news - networking - office apps - order management - other - portfolio management - presentation - pricing - productivity - research - risk - screen sharing - security - spreadsheet - trade cost analysis - trading system - training - travel - video - visualisation - weather + * @return categories + */ + + @Schema(name = "categories", description = "An array of string categories that describe the application. These are meant as a hint to catalogs or stores listing FDC3-enabled apps and it is expected that these will make a best effort to find appropriate categories (or category) under which to list the app. AppD record authors are encouraged to use lower-case and, where possible, to select categories from the following list: - allocations - analytics - charts - chat - communication - compliance - crm - developer tools - events - execution management - file sharing - market data - news - networking - office apps - order management - other - portfolio management - presentation - pricing - productivity - research - risk - screen sharing - security - spreadsheet - trade cost analysis - trading system - training - travel - video - visualisation - weather ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("categories") + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public Application icons(List<@Valid Icon> icons) { + this.icons = icons; + return this; + } + + public Application addIconsItem(Icon iconsItem) { + if (this.icons == null) { + this.icons = new ArrayList<>(); + } + this.icons.add(iconsItem); + return this; + } + + /** + * Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon + * @return icons + */ + @Valid + @Schema(name = "icons", description = "Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("icons") + public List<@Valid Icon> getIcons() { + return icons; + } + + public void setIcons(List<@Valid Icon> icons) { + this.icons = icons; + } + + public Application screenshots(List<@Valid Screenshot> screenshots) { + this.screenshots = screenshots; + return this; + } + + public Application addScreenshotsItem(Screenshot screenshotsItem) { + if (this.screenshots == null) { + this.screenshots = new ArrayList<>(); + } + this.screenshots.add(screenshotsItem); + return this; + } + + /** + * Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip + * @return screenshots + */ + @Valid + @Schema(name = "screenshots", description = "Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("screenshots") + public List<@Valid Screenshot> getScreenshots() { + return screenshots; + } + + public void setScreenshots(List<@Valid Screenshot> screenshots) { + this.screenshots = screenshots; + } + + public Application contactEmail(String contactEmail) { + this.contactEmail = contactEmail; + return this; + } + + /** + * Optional e-mail to receive queries about the application + * @return contactEmail + */ + @Email + @Schema(name = "contactEmail", description = "Optional e-mail to receive queries about the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("contactEmail") + public String getContactEmail() { + return contactEmail; + } + + public void setContactEmail(String contactEmail) { + this.contactEmail = contactEmail; + } + + public Application supportEmail(String supportEmail) { + this.supportEmail = supportEmail; + return this; + } + + /** + * Optional e-mail to receive support requests for the application + * @return supportEmail + */ + @Email + @Schema(name = "supportEmail", description = "Optional e-mail to receive support requests for the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("supportEmail") + public String getSupportEmail() { + return supportEmail; + } + + public void setSupportEmail(String supportEmail) { + this.supportEmail = supportEmail; + } + + public Application moreInfo(URI moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + /** + * Optional URL that provides more infomation about the application + * @return moreInfo + */ + @Valid + @Schema(name = "moreInfo", description = "Optional URL that provides more infomation about the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("moreInfo") + public URI getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(URI moreInfo) { + this.moreInfo = moreInfo; + } + + public Application publisher(String publisher) { + this.publisher = publisher; + return this; + } + + /** + * The name of the company that owns the application. The publisher has control over their namespace/app/signature. + * @return publisher + */ + + @Schema(name = "publisher", description = "The name of the company that owns the application. The publisher has control over their namespace/app/signature.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("publisher") + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public Application customConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + return this; + } + + public Application addCustomConfigItem(NameValuePair customConfigItem) { + if (this.customConfig == null) { + this.customConfig = new ArrayList<>(); + } + this.customConfig.add(customConfigItem); + return this; + } + + /** + * An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher. + * @return customConfig + */ + @Valid + @Schema(name = "customConfig", description = "An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("customConfig") + public List<@Valid NameValuePair> getCustomConfig() { + return customConfig; + } + + public void setCustomConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + } + + public Application hostManifests(Map hostManifests) { + this.hostManifests = hostManifests; + return this; + } + + public Application putHostManifestsItem(String key, HostManifestsValue hostManifestsItem) { + if (this.hostManifests == null) { + this.hostManifests = new HashMap<>(); + } + this.hostManifests.put(key, hostManifestsItem); + return this; + } + + /** + * A mapping from host name to a host-specific application manifest object or URI from which that manifest can be retrieved. The manifest should provide details required to launch and use the application within the specified host. The manifest _MAY_ duplicate or override information provided in the `details` field. + * @return hostManifests + */ + @Valid + @Schema(name = "hostManifests", description = "A mapping from host name to a host-specific application manifest object or URI from which that manifest can be retrieved. The manifest should provide details required to launch and use the application within the specified host. The manifest _MAY_ duplicate or override information provided in the `details` field.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("hostManifests") + public Map getHostManifests() { + return hostManifests; + } + + public void setHostManifests(Map hostManifests) { + this.hostManifests = hostManifests; + } + + public Application interop(Interop interop) { + this.interop = interop; + return this; + } + + /** + * Get interop + * @return interop + */ + @Valid + @Schema(name = "interop", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("interop") + public Interop getInterop() { + return interop; + } + + public void setInterop(Interop interop) { + this.interop = interop; + } + + public Application localizedVersions(Map localizedVersions) { + this.localizedVersions = localizedVersions; + return this; + } + + public Application putLocalizedVersionsItem(String key, BaseApplication localizedVersionsItem) { + if (this.localizedVersions == null) { + this.localizedVersions = new HashMap<>(); + } + this.localizedVersions.put(key, localizedVersionsItem); + return this; + } + + /** + * Provides localized alternatives to any field of the AppD record, which may also refer to an alternative version of the application that is also localized (e.g. by providing customConfig or an alternative URL). The keys to this object should be language tags as defined by IETF RFC 5646, e.g. en, en-GB or fr-FR. + * @return localizedVersions + */ + @Valid + @Schema(name = "localizedVersions", description = "Provides localized alternatives to any field of the AppD record, which may also refer to an alternative version of the application that is also localized (e.g. by providing customConfig or an alternative URL). The keys to this object should be language tags as defined by IETF RFC 5646, e.g. en, en-GB or fr-FR. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("localizedVersions") + public Map getLocalizedVersions() { + return localizedVersions; + } + + public void setLocalizedVersions(Map localizedVersions) { + this.localizedVersions = localizedVersions; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Application application = (Application) o; + return Objects.equals(this.appId, application.appId) && + Objects.equals(this.name, application.name) && + Objects.equals(this.type, application.type) && + Objects.equals(this.details, application.details) && + Objects.equals(this.version, application.version) && + Objects.equals(this.title, application.title) && + Objects.equals(this.tooltip, application.tooltip) && + Objects.equals(this.lang, application.lang) && + Objects.equals(this.description, application.description) && + Objects.equals(this.categories, application.categories) && + Objects.equals(this.icons, application.icons) && + Objects.equals(this.screenshots, application.screenshots) && + Objects.equals(this.contactEmail, application.contactEmail) && + Objects.equals(this.supportEmail, application.supportEmail) && + Objects.equals(this.moreInfo, application.moreInfo) && + Objects.equals(this.publisher, application.publisher) && + Objects.equals(this.customConfig, application.customConfig) && + Objects.equals(this.hostManifests, application.hostManifests) && + Objects.equals(this.interop, application.interop) && + Objects.equals(this.localizedVersions, application.localizedVersions); + } + + @Override + public int hashCode() { + return Objects.hash(appId, name, type, details, version, title, tooltip, lang, description, categories, icons, screenshots, contactEmail, supportEmail, moreInfo, publisher, customConfig, hostManifests, interop, localizedVersions); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Application {\n"); + sb.append(" appId: ").append(toIndentedString(appId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" details: ").append(toIndentedString(details)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" tooltip: ").append(toIndentedString(tooltip)).append("\n"); + sb.append(" lang: ").append(toIndentedString(lang)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" categories: ").append(toIndentedString(categories)).append("\n"); + sb.append(" icons: ").append(toIndentedString(icons)).append("\n"); + sb.append(" screenshots: ").append(toIndentedString(screenshots)).append("\n"); + sb.append(" contactEmail: ").append(toIndentedString(contactEmail)).append("\n"); + sb.append(" supportEmail: ").append(toIndentedString(supportEmail)).append("\n"); + sb.append(" moreInfo: ").append(toIndentedString(moreInfo)).append("\n"); + sb.append(" publisher: ").append(toIndentedString(publisher)).append("\n"); + sb.append(" customConfig: ").append(toIndentedString(customConfig)).append("\n"); + sb.append(" hostManifests: ").append(toIndentedString(hostManifests)).append("\n"); + sb.append(" interop: ").append(toIndentedString(interop)).append("\n"); + sb.append(" localizedVersions: ").append(toIndentedString(localizedVersions)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationSearchResponseV1.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationSearchResponseV1.java new file mode 100755 index 00000000..18d65dcf --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationSearchResponseV1.java @@ -0,0 +1,111 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * ApplicationSearchResponseV1 + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class ApplicationSearchResponseV1 { + + @Valid + private List<@Valid ApplicationV1> applications = new ArrayList<>(); + + private String message; + + public ApplicationSearchResponseV1 applications(List<@Valid ApplicationV1> applications) { + this.applications = applications; + return this; + } + + public ApplicationSearchResponseV1 addApplicationsItem(ApplicationV1 applicationsItem) { + if (this.applications == null) { + this.applications = new ArrayList<>(); + } + this.applications.add(applicationsItem); + return this; + } + + /** + * List of applications + * @return applications + */ + @Valid + @Schema(name = "applications", description = "List of applications ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("applications") + public List<@Valid ApplicationV1> getApplications() { + return applications; + } + + public void setApplications(List<@Valid ApplicationV1> applications) { + this.applications = applications; + } + + public ApplicationSearchResponseV1 message(String message) { + this.message = message; + return this; + } + + /** + * Response message providing status of query + * @return message + */ + + @Schema(name = "message", description = "Response message providing status of query ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApplicationSearchResponseV1 applicationSearchResponseV1 = (ApplicationSearchResponseV1) o; + return Objects.equals(this.applications, applicationSearchResponseV1.applications) && + Objects.equals(this.message, applicationSearchResponseV1.message); + } + + @Override + public int hashCode() { + return Objects.hash(applications, message); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApplicationSearchResponseV1 {\n"); + sb.append(" applications: ").append(toIndentedString(applications)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationV1.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationV1.java new file mode 100755 index 00000000..bd20fa94 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ApplicationV1.java @@ -0,0 +1,467 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * (Deprecated v1 API version) Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec. + */ + +@Schema(name = "ApplicationV1", description = "(Deprecated v1 API version) Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec. ") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class ApplicationV1 { + + private String appId; + + private String name; + + private String manifest; + + private String manifestType; + + private String version; + + private String title; + + private String tooltip; + + private String description; + + @Valid + private List<@Valid AppImageV1> images = new ArrayList<>(); + + private String contactEmail; + + private String supportEmail; + + private String publisher; + + @Valid + private List<@Valid IconV1> icons = new ArrayList<>(); + + @Valid + private List<@Valid NameValuePair> customConfig = new ArrayList<>(); + + @Valid + private List<@Valid IntentV1> intents = new ArrayList<>(); + + public ApplicationV1() { + super(); + } + + /** + * Constructor with only required parameters + */ + public ApplicationV1(String appId, String name, String manifest, String manifestType) { + this.appId = appId; + this.name = name; + this.manifest = manifest; + this.manifestType = manifestType; + } + + public ApplicationV1 appId(String appId) { + this.appId = appId; + return this; + } + + /** + * The unique application identifier located within a specific application directory instance. + * @return appId + */ + @NotNull + @Schema(name = "appId", description = "The unique application identifier located within a specific application directory instance. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("appId") + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public ApplicationV1 name(String name) { + this.name = name; + return this; + } + + /** + * The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. + * @return name + */ + @NotNull + @Schema(name = "name", description = "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ApplicationV1 manifest(String manifest) { + this.manifest = manifest; + return this; + } + + /** + * URI or full JSON of the application manifest providing all details related to launch and use requirements as described by the vendor. The format of this manifest is vendor specific, but can be identified by the manifestType attribute. + * @return manifest + */ + @NotNull + @Schema(name = "manifest", description = "URI or full JSON of the application manifest providing all details related to launch and use requirements as described by the vendor. The format of this manifest is vendor specific, but can be identified by the manifestType attribute. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("manifest") + public String getManifest() { + return manifest; + } + + public void setManifest(String manifest) { + this.manifest = manifest; + } + + public ApplicationV1 manifestType(String manifestType) { + this.manifestType = manifestType; + return this; + } + + /** + * The manifest type which relates to the format and structure of the manifest content. The definition is based on the vendor specific format and definition outside of this specification. + * @return manifestType + */ + @NotNull + @Schema(name = "manifestType", description = "The manifest type which relates to the format and structure of the manifest content. The definition is based on the vendor specific format and definition outside of this specification. ", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("manifestType") + public String getManifestType() { + return manifestType; + } + + public void setManifestType(String manifestType) { + this.manifestType = manifestType; + } + + public ApplicationV1 version(String version) { + this.version = version; + return this; + } + + /** + * Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA) + * @return version + */ + + @Schema(name = "version", description = "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("version") + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public ApplicationV1 title(String title) { + this.title = title; + return this; + } + + /** + * Optional title for the application, if missing use appName, typically used in a launcher UI. + * @return title + */ + + @Schema(name = "title", description = "Optional title for the application, if missing use appName, typically used in a launcher UI.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("title") + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public ApplicationV1 tooltip(String tooltip) { + this.tooltip = tooltip; + return this; + } + + /** + * Optional tooltip description e.g. for a launcher + * @return tooltip + */ + + @Schema(name = "tooltip", description = "Optional tooltip description e.g. for a launcher", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tooltip") + public String getTooltip() { + return tooltip; + } + + public void setTooltip(String tooltip) { + this.tooltip = tooltip; + } + + public ApplicationV1 description(String description) { + this.description = description; + return this; + } + + /** + * Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language + * @return description + */ + + @Schema(name = "description", description = "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ApplicationV1 images(List<@Valid AppImageV1> images) { + this.images = images; + return this; + } + + public ApplicationV1 addImagesItem(AppImageV1 imagesItem) { + if (this.images == null) { + this.images = new ArrayList<>(); + } + this.images.add(imagesItem); + return this; + } + + /** + * Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip + * @return images + */ + @Valid + @Schema(name = "images", description = "Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("images") + public List<@Valid AppImageV1> getImages() { + return images; + } + + public void setImages(List<@Valid AppImageV1> images) { + this.images = images; + } + + public ApplicationV1 contactEmail(String contactEmail) { + this.contactEmail = contactEmail; + return this; + } + + /** + * Optional e-mail to receive queries about the application + * @return contactEmail + */ + @Email + @Schema(name = "contactEmail", description = "Optional e-mail to receive queries about the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("contactEmail") + public String getContactEmail() { + return contactEmail; + } + + public void setContactEmail(String contactEmail) { + this.contactEmail = contactEmail; + } + + public ApplicationV1 supportEmail(String supportEmail) { + this.supportEmail = supportEmail; + return this; + } + + /** + * Optional e-mail to receive support requests for the application + * @return supportEmail + */ + @Email + @Schema(name = "supportEmail", description = "Optional e-mail to receive support requests for the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("supportEmail") + public String getSupportEmail() { + return supportEmail; + } + + public void setSupportEmail(String supportEmail) { + this.supportEmail = supportEmail; + } + + public ApplicationV1 publisher(String publisher) { + this.publisher = publisher; + return this; + } + + /** + * The name of the company that owns the application. The publisher has control over their namespace/app/signature. + * @return publisher + */ + + @Schema(name = "publisher", description = "The name of the company that owns the application. The publisher has control over their namespace/app/signature.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("publisher") + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public ApplicationV1 icons(List<@Valid IconV1> icons) { + this.icons = icons; + return this; + } + + public ApplicationV1 addIconsItem(IconV1 iconsItem) { + if (this.icons == null) { + this.icons = new ArrayList<>(); + } + this.icons.add(iconsItem); + return this; + } + + /** + * Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon + * @return icons + */ + @Valid + @Schema(name = "icons", description = "Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("icons") + public List<@Valid IconV1> getIcons() { + return icons; + } + + public void setIcons(List<@Valid IconV1> icons) { + this.icons = icons; + } + + public ApplicationV1 customConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + return this; + } + + public ApplicationV1 addCustomConfigItem(NameValuePair customConfigItem) { + if (this.customConfig == null) { + this.customConfig = new ArrayList<>(); + } + this.customConfig.add(customConfigItem); + return this; + } + + /** + * An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher. + * @return customConfig + */ + @Valid + @Schema(name = "customConfig", description = "An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("customConfig") + public List<@Valid NameValuePair> getCustomConfig() { + return customConfig; + } + + public void setCustomConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + } + + public ApplicationV1 intents(List<@Valid IntentV1> intents) { + this.intents = intents; + return this; + } + + public ApplicationV1 addIntentsItem(IntentV1 intentsItem) { + if (this.intents == null) { + this.intents = new ArrayList<>(); + } + this.intents.add(intentsItem); + return this; + } + + /** + * The list of intents implemented by the application as defined by https://github.com/FDC3/Intents/blob/master/src/Intent.yaml + * @return intents + */ + @Valid + @Schema(name = "intents", description = "The list of intents implemented by the application as defined by https://github.com/FDC3/Intents/blob/master/src/Intent.yaml ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("intents") + public List<@Valid IntentV1> getIntents() { + return intents; + } + + public void setIntents(List<@Valid IntentV1> intents) { + this.intents = intents; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApplicationV1 applicationV1 = (ApplicationV1) o; + return Objects.equals(this.appId, applicationV1.appId) && + Objects.equals(this.name, applicationV1.name) && + Objects.equals(this.manifest, applicationV1.manifest) && + Objects.equals(this.manifestType, applicationV1.manifestType) && + Objects.equals(this.version, applicationV1.version) && + Objects.equals(this.title, applicationV1.title) && + Objects.equals(this.tooltip, applicationV1.tooltip) && + Objects.equals(this.description, applicationV1.description) && + Objects.equals(this.images, applicationV1.images) && + Objects.equals(this.contactEmail, applicationV1.contactEmail) && + Objects.equals(this.supportEmail, applicationV1.supportEmail) && + Objects.equals(this.publisher, applicationV1.publisher) && + Objects.equals(this.icons, applicationV1.icons) && + Objects.equals(this.customConfig, applicationV1.customConfig) && + Objects.equals(this.intents, applicationV1.intents); + } + + @Override + public int hashCode() { + return Objects.hash(appId, name, manifest, manifestType, version, title, tooltip, description, images, contactEmail, supportEmail, publisher, icons, customConfig, intents); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApplicationV1 {\n"); + sb.append(" appId: ").append(toIndentedString(appId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" manifest: ").append(toIndentedString(manifest)).append("\n"); + sb.append(" manifestType: ").append(toIndentedString(manifestType)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" tooltip: ").append(toIndentedString(tooltip)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" images: ").append(toIndentedString(images)).append("\n"); + sb.append(" contactEmail: ").append(toIndentedString(contactEmail)).append("\n"); + sb.append(" supportEmail: ").append(toIndentedString(supportEmail)).append("\n"); + sb.append(" publisher: ").append(toIndentedString(publisher)).append("\n"); + sb.append(" icons: ").append(toIndentedString(icons)).append("\n"); + sb.append(" customConfig: ").append(toIndentedString(customConfig)).append("\n"); + sb.append(" intents: ").append(toIndentedString(intents)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/BaseApplication.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/BaseApplication.java new file mode 100755 index 00000000..5f1b94bf --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/BaseApplication.java @@ -0,0 +1,556 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; + +import java.net.URI; +import java.util.*; + +/** + * BaseApplication + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class BaseApplication { + + private String appId; + + private String name; + + private Type type; + + private LaunchDetails details; + + private String version; + + private String title; + + private String tooltip; + + private String lang; + + private String description; + + @Valid + private List categories = new ArrayList<>(); + + @Valid + private List<@Valid Icon> icons = new ArrayList<>(); + + @Valid + private List<@Valid Screenshot> screenshots = new ArrayList<>(); + + private String contactEmail; + + private String supportEmail; + + private URI moreInfo; + + private String publisher; + + @Valid + private List<@Valid NameValuePair> customConfig = new ArrayList<>(); + + @Valid + private Map hostManifests = new HashMap<>(); + + private Interop interop; + + public BaseApplication appId(String appId) { + this.appId = appId; + return this; + } + + /** + * The unique application identifier located within a specific application directory instance. + * @return appId + */ + + @Schema(name = "appId", description = "The unique application identifier located within a specific application directory instance. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("appId") + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public BaseApplication name(String name) { + this.name = name; + return this; + } + + /** + * The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. + * @return name + */ + + @Schema(name = "name", description = "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BaseApplication type(Type type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @Valid + @Schema(name = "type", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("type") + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public BaseApplication details(LaunchDetails details) { + this.details = details; + return this; + } + + /** + * Get details + * @return details + */ + @Valid + @Schema(name = "details", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("details") + public LaunchDetails getDetails() { + return details; + } + + public void setDetails(LaunchDetails details) { + this.details = details; + } + + public BaseApplication version(String version) { + this.version = version; + return this; + } + + /** + * Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA) + * @return version + */ + + @Schema(name = "version", description = "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("version") + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public BaseApplication title(String title) { + this.title = title; + return this; + } + + /** + * Optional title for the application, if missing use appName, typically used in a launcher UI. + * @return title + */ + + @Schema(name = "title", description = "Optional title for the application, if missing use appName, typically used in a launcher UI.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("title") + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public BaseApplication tooltip(String tooltip) { + this.tooltip = tooltip; + return this; + } + + /** + * Optional tooltip description e.g. for a launcher + * @return tooltip + */ + + @Schema(name = "tooltip", description = "Optional tooltip description e.g. for a launcher", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tooltip") + public String getTooltip() { + return tooltip; + } + + public void setTooltip(String tooltip) { + this.tooltip = tooltip; + } + + public BaseApplication lang(String lang) { + this.lang = lang; + return this; + } + + /** + * A language tag that specifies the primary language of both the application and its AppD entry, as defined by IETF RFC 5646. + * @return lang + */ + @Pattern(regexp = "^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$") + @Schema(name = "lang", description = "A language tag that specifies the primary language of both the application and its AppD entry, as defined by IETF RFC 5646.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("lang") + public String getLang() { + return lang; + } + + public void setLang(String lang) { + this.lang = lang; + } + + public BaseApplication description(String description) { + this.description = description; + return this; + } + + /** + * Description of the application. This will typically be a 1-2 paragraph style blurb about the application. + * @return description + */ + + @Schema(name = "description", description = "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public BaseApplication categories(List categories) { + this.categories = categories; + return this; + } + + public BaseApplication addCategoriesItem(String categoriesItem) { + if (this.categories == null) { + this.categories = new ArrayList<>(); + } + this.categories.add(categoriesItem); + return this; + } + + /** + * An array of string categories that describe the application. These are meant as a hint to catalogs or stores listing FDC3-enabled apps and it is expected that these will make a best effort to find appropriate categories (or category) under which to list the app. AppD record authors are encouraged to use lower-case and, where possible, to select categories from the following list: - allocations - analytics - charts - chat - communication - compliance - crm - developer tools - events - execution management - file sharing - market data - news - networking - office apps - order management - other - portfolio management - presentation - pricing - productivity - research - risk - screen sharing - security - spreadsheet - trade cost analysis - trading system - training - travel - video - visualisation - weather + * @return categories + */ + + @Schema(name = "categories", description = "An array of string categories that describe the application. These are meant as a hint to catalogs or stores listing FDC3-enabled apps and it is expected that these will make a best effort to find appropriate categories (or category) under which to list the app. AppD record authors are encouraged to use lower-case and, where possible, to select categories from the following list: - allocations - analytics - charts - chat - communication - compliance - crm - developer tools - events - execution management - file sharing - market data - news - networking - office apps - order management - other - portfolio management - presentation - pricing - productivity - research - risk - screen sharing - security - spreadsheet - trade cost analysis - trading system - training - travel - video - visualisation - weather ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("categories") + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public BaseApplication icons(List<@Valid Icon> icons) { + this.icons = icons; + return this; + } + + public BaseApplication addIconsItem(Icon iconsItem) { + if (this.icons == null) { + this.icons = new ArrayList<>(); + } + this.icons.add(iconsItem); + return this; + } + + /** + * Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon + * @return icons + */ + @Valid + @Schema(name = "icons", description = "Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("icons") + public List<@Valid Icon> getIcons() { + return icons; + } + + public void setIcons(List<@Valid Icon> icons) { + this.icons = icons; + } + + public BaseApplication screenshots(List<@Valid Screenshot> screenshots) { + this.screenshots = screenshots; + return this; + } + + public BaseApplication addScreenshotsItem(Screenshot screenshotsItem) { + if (this.screenshots == null) { + this.screenshots = new ArrayList<>(); + } + this.screenshots.add(screenshotsItem); + return this; + } + + /** + * Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip + * @return screenshots + */ + @Valid + @Schema(name = "screenshots", description = "Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("screenshots") + public List<@Valid Screenshot> getScreenshots() { + return screenshots; + } + + public void setScreenshots(List<@Valid Screenshot> screenshots) { + this.screenshots = screenshots; + } + + public BaseApplication contactEmail(String contactEmail) { + this.contactEmail = contactEmail; + return this; + } + + /** + * Optional e-mail to receive queries about the application + * @return contactEmail + */ + @Email + @Schema(name = "contactEmail", description = "Optional e-mail to receive queries about the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("contactEmail") + public String getContactEmail() { + return contactEmail; + } + + public void setContactEmail(String contactEmail) { + this.contactEmail = contactEmail; + } + + public BaseApplication supportEmail(String supportEmail) { + this.supportEmail = supportEmail; + return this; + } + + /** + * Optional e-mail to receive support requests for the application + * @return supportEmail + */ + @Email + @Schema(name = "supportEmail", description = "Optional e-mail to receive support requests for the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("supportEmail") + public String getSupportEmail() { + return supportEmail; + } + + public void setSupportEmail(String supportEmail) { + this.supportEmail = supportEmail; + } + + public BaseApplication moreInfo(URI moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + /** + * Optional URL that provides more infomation about the application + * @return moreInfo + */ + @Valid + @Schema(name = "moreInfo", description = "Optional URL that provides more infomation about the application", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("moreInfo") + public URI getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(URI moreInfo) { + this.moreInfo = moreInfo; + } + + public BaseApplication publisher(String publisher) { + this.publisher = publisher; + return this; + } + + /** + * The name of the company that owns the application. The publisher has control over their namespace/app/signature. + * @return publisher + */ + + @Schema(name = "publisher", description = "The name of the company that owns the application. The publisher has control over their namespace/app/signature.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("publisher") + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public BaseApplication customConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + return this; + } + + public BaseApplication addCustomConfigItem(NameValuePair customConfigItem) { + if (this.customConfig == null) { + this.customConfig = new ArrayList<>(); + } + this.customConfig.add(customConfigItem); + return this; + } + + /** + * An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher. + * @return customConfig + */ + @Valid + @Schema(name = "customConfig", description = "An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("customConfig") + public List<@Valid NameValuePair> getCustomConfig() { + return customConfig; + } + + public void setCustomConfig(List<@Valid NameValuePair> customConfig) { + this.customConfig = customConfig; + } + + public BaseApplication hostManifests(Map hostManifests) { + this.hostManifests = hostManifests; + return this; + } + + public BaseApplication putHostManifestsItem(String key, HostManifestsValue hostManifestsItem) { + if (this.hostManifests == null) { + this.hostManifests = new HashMap<>(); + } + this.hostManifests.put(key, hostManifestsItem); + return this; + } + + /** + * A mapping from host name to a host-specific application manifest object or URI from which that manifest can be retrieved. The manifest should provide details required to launch and use the application within the specified host. The manifest _MAY_ duplicate or override information provided in the `details` field. + * @return hostManifests + */ + @Valid + @Schema(name = "hostManifests", description = "A mapping from host name to a host-specific application manifest object or URI from which that manifest can be retrieved. The manifest should provide details required to launch and use the application within the specified host. The manifest _MAY_ duplicate or override information provided in the `details` field.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("hostManifests") + public Map getHostManifests() { + return hostManifests; + } + + public void setHostManifests(Map hostManifests) { + this.hostManifests = hostManifests; + } + + public BaseApplication interop(Interop interop) { + this.interop = interop; + return this; + } + + /** + * Get interop + * @return interop + */ + @Valid + @Schema(name = "interop", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("interop") + public Interop getInterop() { + return interop; + } + + public void setInterop(Interop interop) { + this.interop = interop; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BaseApplication baseApplication = (BaseApplication) o; + return Objects.equals(this.appId, baseApplication.appId) && + Objects.equals(this.name, baseApplication.name) && + Objects.equals(this.type, baseApplication.type) && + Objects.equals(this.details, baseApplication.details) && + Objects.equals(this.version, baseApplication.version) && + Objects.equals(this.title, baseApplication.title) && + Objects.equals(this.tooltip, baseApplication.tooltip) && + Objects.equals(this.lang, baseApplication.lang) && + Objects.equals(this.description, baseApplication.description) && + Objects.equals(this.categories, baseApplication.categories) && + Objects.equals(this.icons, baseApplication.icons) && + Objects.equals(this.screenshots, baseApplication.screenshots) && + Objects.equals(this.contactEmail, baseApplication.contactEmail) && + Objects.equals(this.supportEmail, baseApplication.supportEmail) && + Objects.equals(this.moreInfo, baseApplication.moreInfo) && + Objects.equals(this.publisher, baseApplication.publisher) && + Objects.equals(this.customConfig, baseApplication.customConfig) && + Objects.equals(this.hostManifests, baseApplication.hostManifests) && + Objects.equals(this.interop, baseApplication.interop); + } + + @Override + public int hashCode() { + return Objects.hash(appId, name, type, details, version, title, tooltip, lang, description, categories, icons, screenshots, contactEmail, supportEmail, moreInfo, publisher, customConfig, hostManifests, interop); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BaseApplication {\n"); + sb.append(" appId: ").append(toIndentedString(appId)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" details: ").append(toIndentedString(details)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" tooltip: ").append(toIndentedString(tooltip)).append("\n"); + sb.append(" lang: ").append(toIndentedString(lang)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" categories: ").append(toIndentedString(categories)).append("\n"); + sb.append(" icons: ").append(toIndentedString(icons)).append("\n"); + sb.append(" screenshots: ").append(toIndentedString(screenshots)).append("\n"); + sb.append(" contactEmail: ").append(toIndentedString(contactEmail)).append("\n"); + sb.append(" supportEmail: ").append(toIndentedString(supportEmail)).append("\n"); + sb.append(" moreInfo: ").append(toIndentedString(moreInfo)).append("\n"); + sb.append(" publisher: ").append(toIndentedString(publisher)).append("\n"); + sb.append(" customConfig: ").append(toIndentedString(customConfig)).append("\n"); + sb.append(" hostManifests: ").append(toIndentedString(hostManifests)).append("\n"); + sb.append(" interop: ").append(toIndentedString(interop)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/CitrixAppDetails.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/CitrixAppDetails.java new file mode 100755 index 00000000..ff82c91b --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/CitrixAppDetails.java @@ -0,0 +1,112 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.constraints.NotNull; + +import java.util.Objects; + +/** + * Properties used to launch apps virtualized apps with `type: citrix`. + */ + +@Schema(name = "CitrixAppDetails", description = "Properties used to launch apps virtualized apps with `type: citrix`.") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class CitrixAppDetails implements LaunchDetails { + + private String alias; + + private String arguments; + + public CitrixAppDetails() { + super(); + } + + /** + * Constructor with only required parameters + */ + public CitrixAppDetails(String alias) { + this.alias = alias; + } + + public CitrixAppDetails alias(String alias) { + this.alias = alias; + return this; + } + + /** + * The Citrix alias / name of the virtual app (passed to the Citrix SelfService qlaunch parameter). + * @return alias + */ + @NotNull + @Schema(name = "alias", description = "The Citrix alias / name of the virtual app (passed to the Citrix SelfService qlaunch parameter).", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("alias") + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public CitrixAppDetails arguments(String arguments) { + this.arguments = arguments; + return this; + } + + /** + * Arguments that must be passed on the command line to launch the app in the expected configuration. + * @return arguments + */ + + @Schema(name = "arguments", description = "Arguments that must be passed on the command line to launch the app in the expected configuration.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("arguments") + public String getArguments() { + return arguments; + } + + public void setArguments(String arguments) { + this.arguments = arguments; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CitrixAppDetails citrixAppDetails = (CitrixAppDetails) o; + return Objects.equals(this.alias, citrixAppDetails.alias) && + Objects.equals(this.arguments, citrixAppDetails.arguments); + } + + @Override + public int hashCode() { + return Objects.hash(alias, arguments); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CitrixAppDetails {\n"); + sb.append(" alias: ").append(toIndentedString(alias)).append("\n"); + sb.append(" arguments: ").append(toIndentedString(arguments)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ErrorDTO.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ErrorDTO.java new file mode 100755 index 00000000..235a8bed --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/ErrorDTO.java @@ -0,0 +1,99 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; + +import java.util.Objects; + +/** + * ErrorDTO + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class ErrorDTO { + + private Integer code; + + private String message; + + public ErrorDTO code(Integer code) { + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + + @Schema(name = "code", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("code") + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public ErrorDTO message(String message) { + this.message = message; + return this; + } + + /** + * Get message + * @return message + */ + + @Schema(name = "message", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ErrorDTO errorDTO = (ErrorDTO) o; + return Objects.equals(this.code, errorDTO.code) && + Objects.equals(this.message, errorDTO.message); + } + + @Override + public int hashCode() { + return Objects.hash(code, message); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ErrorDTO {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/HostManifestsValue.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/HostManifestsValue.java new file mode 100755 index 00000000..f0c46765 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/HostManifestsValue.java @@ -0,0 +1,9 @@ +package com.fdc.appd.model; + + +import jakarta.annotation.Generated; + + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public interface HostManifestsValue { +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Icon.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Icon.java new file mode 100755 index 00000000..bef4265e --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Icon.java @@ -0,0 +1,126 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.net.URI; +import java.util.Objects; + +/** + * Icon holder + */ + +@Schema(name = "Icon", description = "Icon holder") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class Icon { + + private URI src; + + private String size; + + private String type; + + public Icon src(URI src) { + this.src = src; + return this; + } + + /** + * Icon URL + * @return src + */ + @Valid + @Schema(name = "src", description = "Icon URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("src") + public URI getSrc() { + return src; + } + + public void setSrc(URI src) { + this.src = src; + } + + public Icon size(String size) { + this.size = size; + return this; + } + + /** + * Icon dimension formatted as `x` + * @return size + */ + + @Schema(name = "size", description = "Icon dimension formatted as `x`", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("size") + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public Icon type(String type) { + this.type = type; + return this; + } + + /** + * Image media type. If not present the Desktop Agent may use the src file extension + * @return type + */ + + @Schema(name = "type", description = "Image media type. If not present the Desktop Agent may use the src file extension", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("type") + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Icon icon = (Icon) o; + return Objects.equals(this.src, icon.src) && + Objects.equals(this.size, icon.size) && + Objects.equals(this.type, icon.type); + } + + @Override + public int hashCode() { + return Objects.hash(src, size, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Icon {\n"); + sb.append(" src: ").append(toIndentedString(src)).append("\n"); + sb.append(" size: ").append(toIndentedString(size)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IconV1.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IconV1.java new file mode 100755 index 00000000..65ce8538 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IconV1.java @@ -0,0 +1,78 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.net.URI; +import java.util.Objects; + +/** + * (Deprecated v1 API version) Icon holder + */ + +@Schema(name = "IconV1", description = "(Deprecated v1 API version) Icon holder") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class IconV1 { + + private URI icon; + + public IconV1 icon(URI icon) { + this.icon = icon; + return this; + } + + /** + * Icon URL + * @return icon + */ + @Valid + @Schema(name = "icon", description = "Icon URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("icon") + public URI getIcon() { + return icon; + } + + public void setIcon(URI icon) { + this.icon = icon; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IconV1 iconV1 = (IconV1) o; + return Objects.equals(this.icon, iconV1.icon); + } + + @Override + public int hashCode() { + return Objects.hash(icon); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class IconV1 {\n"); + sb.append(" icon: ").append(toIndentedString(icon)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Intent.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Intent.java new file mode 100755 index 00000000..84f43e3e --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Intent.java @@ -0,0 +1,172 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Definition of an intent that an app listens for + */ + +@Schema(name = "Intent", description = "Definition of an intent that an app listens for") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class Intent { + + private String displayName; + + @Valid + private List contexts = new ArrayList<>(); + + private String resultType; + + private Object customConfig; + + public Intent() { + super(); + } + + /** + * Constructor with only required parameters + */ + public Intent(List contexts) { + this.contexts = contexts; + } + + public Intent displayName(String displayName) { + this.displayName = displayName; + return this; + } + + /** + * An optional display name for the intent that may be used in UI instead of the name. + * @return displayName + */ + + @Schema(name = "displayName", description = "An optional display name for the intent that may be used in UI instead of the name.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("displayName") + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Intent contexts(List contexts) { + this.contexts = contexts; + return this; + } + + public Intent addContextsItem(String contextsItem) { + if (this.contexts == null) { + this.contexts = new ArrayList<>(); + } + this.contexts.add(contextsItem); + return this; + } + + /** + * A comma separated list of the types of contexts the intent offered by the application can process, where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\" + * @return contexts + */ + @NotNull + @Schema(name = "contexts", description = "A comma separated list of the types of contexts the intent offered by the application can process, where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\"", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("contexts") + public List getContexts() { + return contexts; + } + + public void setContexts(List contexts) { + this.contexts = contexts; + } + + public Intent resultType(String resultType) { + this.resultType = resultType; + return this; + } + + /** + * An optional type for output returned by the application, if any, when resolving this intent. May indicate a context type by type name (e.g. \"fdc3.instrument\"), a channel (e.g. \"channel\") or a combination that indicates a channel that returns a particular context type (e.g. \"channel\"). + * @return resultType + */ + + @Schema(name = "resultType", description = "An optional type for output returned by the application, if any, when resolving this intent. May indicate a context type by type name (e.g. \"fdc3.instrument\"), a channel (e.g. \"channel\") or a combination that indicates a channel that returns a particular context type (e.g. \"channel\").", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("resultType") + public String getResultType() { + return resultType; + } + + public void setResultType(String resultType) { + this.resultType = resultType; + } + + public Intent customConfig(Object customConfig) { + this.customConfig = customConfig; + return this; + } + + /** + * Custom configuration for the intent that may be required for a particular desktop agent. + * @return customConfig + */ + + @Schema(name = "customConfig", description = "Custom configuration for the intent that may be required for a particular desktop agent.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("customConfig") + public Object getCustomConfig() { + return customConfig; + } + + public void setCustomConfig(Object customConfig) { + this.customConfig = customConfig; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Intent intent = (Intent) o; + return Objects.equals(this.displayName, intent.displayName) && + Objects.equals(this.contexts, intent.contexts) && + Objects.equals(this.resultType, intent.resultType) && + Objects.equals(this.customConfig, intent.customConfig); + } + + @Override + public int hashCode() { + return Objects.hash(displayName, contexts, resultType, customConfig); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Intent {\n"); + sb.append(" displayName: ").append(toIndentedString(displayName)).append("\n"); + sb.append(" contexts: ").append(toIndentedString(contexts)).append("\n"); + sb.append(" resultType: ").append(toIndentedString(resultType)).append("\n"); + sb.append(" customConfig: ").append(toIndentedString(customConfig)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IntentV1.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IntentV1.java new file mode 100755 index 00000000..ce498b76 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/IntentV1.java @@ -0,0 +1,172 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * (Deprecated v1 API version) An intent definition as defined by spec https://github.com/FDC3/Intents/blob/master/src/Intent.yaml + */ + +@Schema(name = "IntentV1", description = "(Deprecated v1 API version) An intent definition as defined by spec https://github.com/FDC3/Intents/blob/master/src/Intent.yaml") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class IntentV1 { + + private String name; + + private String displayName; + + @Valid + private List contexts = new ArrayList<>(); + + private Object customConfig; + + public IntentV1() { + super(); + } + + /** + * Constructor with only required parameters + */ + public IntentV1(String name) { + this.name = name; + } + + public IntentV1 name(String name) { + this.name = name; + return this; + } + + /** + * The name of the intent to 'launch'. In this case the name of an Intent supported by an application. + * @return name + */ + @NotNull + @Schema(name = "name", description = "The name of the intent to 'launch'. In this case the name of an Intent supported by an application.", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public IntentV1 displayName(String displayName) { + this.displayName = displayName; + return this; + } + + /** + * An optional display name for the intent that may be used in UI instead of the name. + * @return displayName + */ + + @Schema(name = "displayName", description = "An optional display name for the intent that may be used in UI instead of the name.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("displayName") + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public IntentV1 contexts(List contexts) { + this.contexts = contexts; + return this; + } + + public IntentV1 addContextsItem(String contextsItem) { + if (this.contexts == null) { + this.contexts = new ArrayList<>(); + } + this.contexts.add(contextsItem); + return this; + } + + /** + * A comma sepaarted list of the types of contexts the intent offered by the application can process. where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\" + * @return contexts + */ + + @Schema(name = "contexts", description = "A comma sepaarted list of the types of contexts the intent offered by the application can process. where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\"", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("contexts") + public List getContexts() { + return contexts; + } + + public void setContexts(List contexts) { + this.contexts = contexts; + } + + public IntentV1 customConfig(Object customConfig) { + this.customConfig = customConfig; + return this; + } + + /** + * Custom configuration for the intent that may be required for a particular desktop agent. + * @return customConfig + */ + + @Schema(name = "customConfig", description = "Custom configuration for the intent that may be required for a particular desktop agent.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("customConfig") + public Object getCustomConfig() { + return customConfig; + } + + public void setCustomConfig(Object customConfig) { + this.customConfig = customConfig; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IntentV1 intentV1 = (IntentV1) o; + return Objects.equals(this.name, intentV1.name) && + Objects.equals(this.displayName, intentV1.displayName) && + Objects.equals(this.contexts, intentV1.contexts) && + Objects.equals(this.customConfig, intentV1.customConfig); + } + + @Override + public int hashCode() { + return Objects.hash(name, displayName, contexts, customConfig); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class IntentV1 {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" displayName: ").append(toIndentedString(displayName)).append("\n"); + sb.append(" contexts: ").append(toIndentedString(contexts)).append("\n"); + sb.append(" customConfig: ").append(toIndentedString(customConfig)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Interop.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Interop.java new file mode 100755 index 00000000..6166de2b --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Interop.java @@ -0,0 +1,136 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Metadata that describes how the application uses FDC3 APIs. This metadata serves multiple purposes: - It supports intent resolution by a desktop agent, by declaring what intents an app listens for. - It may be used, for example in an app catalog UI, to find apps that 'interoperate with' other apps. - It provides a standard location to document how the app interacts with user channels, app channels, and intents, for use by other app developers and desktop assemblers. + */ + +@Schema(name = "Interop", description = "Metadata that describes how the application uses FDC3 APIs. This metadata serves multiple purposes: - It supports intent resolution by a desktop agent, by declaring what intents an app listens for. - It may be used, for example in an app catalog UI, to find apps that 'interoperate with' other apps. - It provides a standard location to document how the app interacts with user channels, app channels, and intents, for use by other app developers and desktop assemblers. ") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class Interop { + + private InteropIntents intents; + + private InteropUserChannels userChannels; + + @Valid + private List<@Valid InteropAppChannelsInner> appChannels = new ArrayList<>(); + + public Interop intents(InteropIntents intents) { + this.intents = intents; + return this; + } + + /** + * Get intents + * @return intents + */ + @Valid + @Schema(name = "intents", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("intents") + public InteropIntents getIntents() { + return intents; + } + + public void setIntents(InteropIntents intents) { + this.intents = intents; + } + + public Interop userChannels(InteropUserChannels userChannels) { + this.userChannels = userChannels; + return this; + } + + /** + * Get userChannels + * @return userChannels + */ + @Valid + @Schema(name = "userChannels", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("userChannels") + public InteropUserChannels getUserChannels() { + return userChannels; + } + + public void setUserChannels(InteropUserChannels userChannels) { + this.userChannels = userChannels; + } + + public Interop appChannels(List<@Valid InteropAppChannelsInner> appChannels) { + this.appChannels = appChannels; + return this; + } + + public Interop addAppChannelsItem(InteropAppChannelsInner appChannelsItem) { + if (this.appChannels == null) { + this.appChannels = new ArrayList<>(); + } + this.appChannels.add(appChannelsItem); + return this; + } + + /** + * Describes the application's use of App Channels. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. + * @return appChannels + */ + @Valid + @Schema(name = "appChannels", description = "Describes the application's use of App Channels. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("appChannels") + public List<@Valid InteropAppChannelsInner> getAppChannels() { + return appChannels; + } + + public void setAppChannels(List<@Valid InteropAppChannelsInner> appChannels) { + this.appChannels = appChannels; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Interop interop = (Interop) o; + return Objects.equals(this.intents, interop.intents) && + Objects.equals(this.userChannels, interop.userChannels) && + Objects.equals(this.appChannels, interop.appChannels); + } + + @Override + public int hashCode() { + return Objects.hash(intents, userChannels, appChannels); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Interop {\n"); + sb.append(" intents: ").append(toIndentedString(intents)).append("\n"); + sb.append(" userChannels: ").append(toIndentedString(userChannels)).append("\n"); + sb.append(" appChannels: ").append(toIndentedString(appChannels)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropAppChannelsInner.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropAppChannelsInner.java new file mode 100755 index 00000000..f1a41524 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropAppChannelsInner.java @@ -0,0 +1,182 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * InteropAppChannelsInner + */ + +@JsonTypeName("Interop_appChannels_inner") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class InteropAppChannelsInner { + + private String name; + + private String description; + + @Valid + private List broadcasts = new ArrayList<>(); + + @Valid + private List listensFor = new ArrayList<>(); + + public InteropAppChannelsInner() { + super(); + } + + /** + * Constructor with only required parameters + */ + public InteropAppChannelsInner(String name) { + this.name = name; + } + + public InteropAppChannelsInner name(String name) { + this.name = name; + return this; + } + + /** + * The name of the App Channel. + * @return name + */ + @NotNull + @Schema(name = "name", description = "The name of the App Channel.", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public InteropAppChannelsInner description(String description) { + this.description = description; + return this; + } + + /** + * A description of how the channel is used. + * @return description + */ + + @Schema(name = "description", description = "A description of how the channel is used.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public InteropAppChannelsInner broadcasts(List broadcasts) { + this.broadcasts = broadcasts; + return this; + } + + public InteropAppChannelsInner addBroadcastsItem(String broadcastsItem) { + if (this.broadcasts == null) { + this.broadcasts = new ArrayList<>(); + } + this.broadcasts.add(broadcastsItem); + return this; + } + + /** + * Context type names that are broadcast by the application on the channel. + * @return broadcasts + */ + + @Schema(name = "broadcasts", description = "Context type names that are broadcast by the application on the channel.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("broadcasts") + public List getBroadcasts() { + return broadcasts; + } + + public void setBroadcasts(List broadcasts) { + this.broadcasts = broadcasts; + } + + public InteropAppChannelsInner listensFor(List listensFor) { + this.listensFor = listensFor; + return this; + } + + public InteropAppChannelsInner addListensForItem(String listensForItem) { + if (this.listensFor == null) { + this.listensFor = new ArrayList<>(); + } + this.listensFor.add(listensForItem); + return this; + } + + /** + * Context type names that the application listens for on the channel. + * @return listensFor + */ + + @Schema(name = "listensFor", description = "Context type names that the application listens for on the channel.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("listensFor") + public List getListensFor() { + return listensFor; + } + + public void setListensFor(List listensFor) { + this.listensFor = listensFor; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InteropAppChannelsInner interopAppChannelsInner = (InteropAppChannelsInner) o; + return Objects.equals(this.name, interopAppChannelsInner.name) && + Objects.equals(this.description, interopAppChannelsInner.description) && + Objects.equals(this.broadcasts, interopAppChannelsInner.broadcasts) && + Objects.equals(this.listensFor, interopAppChannelsInner.listensFor); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, broadcasts, listensFor); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class InteropAppChannelsInner {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" broadcasts: ").append(toIndentedString(broadcasts)).append("\n"); + sb.append(" listensFor: ").append(toIndentedString(listensFor)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropIntents.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropIntents.java new file mode 100755 index 00000000..47ad1826 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropIntents.java @@ -0,0 +1,123 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Describes the app's interactions with intents. + */ + +@Schema(name = "Interop_intents", description = "Describes the app's interactions with intents.") +@JsonTypeName("Interop_intents") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class InteropIntents { + + @Valid + private Map listensFor = new HashMap<>(); + + @Valid + private Map raises = new HashMap<>(); + + public InteropIntents listensFor(Map listensFor) { + this.listensFor = listensFor; + return this; + } + + public InteropIntents putListensForItem(String key, Intent listensForItem) { + if (this.listensFor == null) { + this.listensFor = new HashMap<>(); + } + this.listensFor.put(key, listensForItem); + return this; + } + + /** + * A mapping of Intents names that an app listens for via `fdc3.addIntentListener()` to their configuration. Used to support intent resolution by desktop agents. Replaces the `intents` element used in appD records prior to FDC3 2.0. + * @return listensFor + */ + @Valid + @Schema(name = "listensFor", description = "A mapping of Intents names that an app listens for via `fdc3.addIntentListener()` to their configuration. Used to support intent resolution by desktop agents. Replaces the `intents` element used in appD records prior to FDC3 2.0. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("listensFor") + public Map getListensFor() { + return listensFor; + } + + public void setListensFor(Map listensFor) { + this.listensFor = listensFor; + } + + public InteropIntents raises(Map raises) { + this.raises = raises; + return this; + } + + public InteropIntents putRaisesItem(String key, Intent raisesItem) { + if (this.raises == null) { + this.raises = new HashMap<>(); + } + this.raises.put(key, raisesItem); + return this; + } + + /** + * A mapping of Intent names that an app raises (via `fdc3.raiseIntent`) to an array of context type names that it may be raised with. Use the intent name \"any\" to represent use of the `fdc3.raiseIntentForContext` and `fdc3.findIntentForContext` functions, which allow the user to select from intents available for a specified context type. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. + * @return raises + */ + @Valid + @Schema(name = "raises", description = "A mapping of Intent names that an app raises (via `fdc3.raiseIntent`) to an array of context type names that it may be raised with. Use the intent name \"any\" to represent use of the `fdc3.raiseIntentForContext` and `fdc3.findIntentForContext` functions, which allow the user to select from intents available for a specified context type. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("raises") + public Map getRaises() { + return raises; + } + + public void setRaises(Map raises) { + this.raises = raises; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InteropIntents interopIntents = (InteropIntents) o; + return Objects.equals(this.listensFor, interopIntents.listensFor) && + Objects.equals(this.raises, interopIntents.raises); + } + + @Override + public int hashCode() { + return Objects.hash(listensFor, raises); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class InteropIntents {\n"); + sb.append(" listensFor: ").append(toIndentedString(listensFor)).append("\n"); + sb.append(" raises: ").append(toIndentedString(raises)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropUserChannels.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropUserChannels.java new file mode 100755 index 00000000..f095f06d --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/InteropUserChannels.java @@ -0,0 +1,123 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Describes the application's use of context types on User Channels. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. + */ + +@Schema(name = "Interop_userChannels", description = "Describes the application's use of context types on User Channels. This metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers. ") +@JsonTypeName("Interop_userChannels") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class InteropUserChannels { + + @Valid + private List broadcasts = new ArrayList<>(); + + @Valid + private List listensFor = new ArrayList<>(); + + public InteropUserChannels broadcasts(List broadcasts) { + this.broadcasts = broadcasts; + return this; + } + + public InteropUserChannels addBroadcastsItem(String broadcastsItem) { + if (this.broadcasts == null) { + this.broadcasts = new ArrayList<>(); + } + this.broadcasts.add(broadcastsItem); + return this; + } + + /** + * Context type names that are broadcast by the application. + * @return broadcasts + */ + + @Schema(name = "broadcasts", description = "Context type names that are broadcast by the application.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("broadcasts") + public List getBroadcasts() { + return broadcasts; + } + + public void setBroadcasts(List broadcasts) { + this.broadcasts = broadcasts; + } + + public InteropUserChannels listensFor(List listensFor) { + this.listensFor = listensFor; + return this; + } + + public InteropUserChannels addListensForItem(String listensForItem) { + if (this.listensFor == null) { + this.listensFor = new ArrayList<>(); + } + this.listensFor.add(listensForItem); + return this; + } + + /** + * Context type names that the application listens for. + * @return listensFor + */ + + @Schema(name = "listensFor", description = "Context type names that the application listens for.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("listensFor") + public List getListensFor() { + return listensFor; + } + + public void setListensFor(List listensFor) { + this.listensFor = listensFor; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InteropUserChannels interopUserChannels = (InteropUserChannels) o; + return Objects.equals(this.broadcasts, interopUserChannels.broadcasts) && + Objects.equals(this.listensFor, interopUserChannels.listensFor); + } + + @Override + public int hashCode() { + return Objects.hash(broadcasts, listensFor); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class InteropUserChannels {\n"); + sb.append(" broadcasts: ").append(toIndentedString(broadcasts)).append("\n"); + sb.append(" listensFor: ").append(toIndentedString(listensFor)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/LaunchDetails.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/LaunchDetails.java new file mode 100755 index 00000000..68c1c908 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/LaunchDetails.java @@ -0,0 +1,9 @@ +package com.fdc.appd.model; + + +import jakarta.annotation.Generated; + + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public interface LaunchDetails { +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NameValuePair.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NameValuePair.java new file mode 100755 index 00000000..a0fd40e0 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NameValuePair.java @@ -0,0 +1,100 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; + +import java.util.Objects; + +/** + * Simple name value pair + */ + +@Schema(name = "NameValuePair", description = "Simple name value pair") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class NameValuePair { + + private String name; + + private String value; + + public NameValuePair name(String name) { + this.name = name; + return this; + } + + /** + * name + * @return name + */ + + @Schema(name = "name", description = "name", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public NameValuePair value(String value) { + this.value = value; + return this; + } + + /** + * value + * @return value + */ + + @Schema(name = "value", description = "value", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("value") + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NameValuePair nameValuePair = (NameValuePair) o; + return Objects.equals(this.name, nameValuePair.name) && + Objects.equals(this.value, nameValuePair.value); + } + + @Override + public int hashCode() { + return Objects.hash(name, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NameValuePair {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NativeAppDetails.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NativeAppDetails.java new file mode 100755 index 00000000..865e0648 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/NativeAppDetails.java @@ -0,0 +1,112 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.constraints.NotNull; + +import java.util.Objects; + +/** + * Properties used to launch apps with `type: native` that are already installed on the device. + */ + +@Schema(name = "NativeAppDetails", description = "Properties used to launch apps with `type: native` that are already installed on the device.") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class NativeAppDetails implements LaunchDetails { + + private String path; + + private String arguments; + + public NativeAppDetails() { + super(); + } + + /** + * Constructor with only required parameters + */ + public NativeAppDetails(String path) { + this.path = path; + } + + public NativeAppDetails path(String path) { + this.path = path; + return this; + } + + /** + * The path on disk from which the application is launched. + * @return path + */ + @NotNull + @Schema(name = "path", description = "The path on disk from which the application is launched.", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("path") + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public NativeAppDetails arguments(String arguments) { + this.arguments = arguments; + return this; + } + + /** + * Arguments that must be passed on the command line to launch the app in the expected configuration. + * @return arguments + */ + + @Schema(name = "arguments", description = "Arguments that must be passed on the command line to launch the app in the expected configuration.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("arguments") + public String getArguments() { + return arguments; + } + + public void setArguments(String arguments) { + this.arguments = arguments; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NativeAppDetails nativeAppDetails = (NativeAppDetails) o; + return Objects.equals(this.path, nativeAppDetails.path) && + Objects.equals(this.arguments, nativeAppDetails.arguments); + } + + @Override + public int hashCode() { + return Objects.hash(path, arguments); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NativeAppDetails {\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" arguments: ").append(toIndentedString(arguments)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/OnlineNativeAppDetails.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/OnlineNativeAppDetails.java new file mode 100755 index 00000000..88b8336d --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/OnlineNativeAppDetails.java @@ -0,0 +1,90 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.net.URI; +import java.util.Objects; + +/** + * Properties used to launch a native apps with `type: onlineNative` that have an online launcher, e.g. online ClickOnce app deployments. + */ + +@Schema(name = "OnlineNativeAppDetails", description = "Properties used to launch a native apps with `type: onlineNative` that have an online launcher, e.g. online ClickOnce app deployments.") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class OnlineNativeAppDetails implements LaunchDetails { + + private URI url; + + public OnlineNativeAppDetails() { + super(); + } + + /** + * Constructor with only required parameters + */ + public OnlineNativeAppDetails(URI url) { + this.url = url; + } + + public OnlineNativeAppDetails url(URI url) { + this.url = url; + return this; + } + + /** + * Application URL. + * @return url + */ + @NotNull @Valid + @Schema(name = "url", description = "Application URL.", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("url") + public URI getUrl() { + return url; + } + + public void setUrl(URI url) { + this.url = url; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OnlineNativeAppDetails onlineNativeAppDetails = (OnlineNativeAppDetails) o; + return Objects.equals(this.url, onlineNativeAppDetails.url); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class OnlineNativeAppDetails {\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Screenshot.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Screenshot.java new file mode 100755 index 00000000..5e39a08e --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Screenshot.java @@ -0,0 +1,150 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; + +import java.net.URI; +import java.util.Objects; + +/** + * Images representing the app in common usage scenarios + */ + +@Schema(name = "Screenshot", description = "Images representing the app in common usage scenarios") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class Screenshot { + + private URI src; + + private String size; + + private String type; + + private String label; + + public Screenshot src(URI src) { + this.src = src; + return this; + } + + /** + * App Image URL + * @return src + */ + @Valid + @Schema(name = "src", description = "App Image URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("src") + public URI getSrc() { + return src; + } + + public void setSrc(URI src) { + this.src = src; + } + + public Screenshot size(String size) { + this.size = size; + return this; + } + + /** + * Image dimension formatted as `x` + * @return size + */ + + @Schema(name = "size", description = "Image dimension formatted as `x`", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("size") + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public Screenshot type(String type) { + this.type = type; + return this; + } + + /** + * Image media type. If not present the Desktop Agent may use the src file extension. + * @return type + */ + + @Schema(name = "type", description = "Image media type. If not present the Desktop Agent may use the src file extension.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("type") + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Screenshot label(String label) { + this.label = label; + return this; + } + + /** + * Optional caption for the image + * @return label + */ + + @Schema(name = "label", description = "Optional caption for the image", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("label") + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Screenshot screenshot = (Screenshot) o; + return Objects.equals(this.src, screenshot.src) && + Objects.equals(this.size, screenshot.size) && + Objects.equals(this.type, screenshot.type) && + Objects.equals(this.label, screenshot.label); + } + + @Override + public int hashCode() { + return Objects.hash(src, size, type, label); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Screenshot {\n"); + sb.append(" src: ").append(toIndentedString(src)).append("\n"); + sb.append(" size: ").append(toIndentedString(size)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" label: ").append(toIndentedString(label)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Type.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Type.java new file mode 100755 index 00000000..a03ba7bb --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/Type.java @@ -0,0 +1,50 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.annotation.Generated; + +/** + * The technology type that is used to launch and run the application. Each application type implies a particular set of launch `details`. The supported types include: - `web`: Web applications launched via a URL - `native`: Native applications pre-installed on a device and launch via a filesystem path - `citrix`: Apps virtualized via Citrix - `onlineNative`: Native apps that have an online launcher, e.g. online ClickOnce app deployments. - `other`: Used to represent apps that do not conform to or cannot be launched via the other types, and are likely to be defined solely by a hostManifest. FDC3 Desktop Agents MUST support at least the `web` application type and MAY support any or all of the other types. + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public enum Type { + + WEB("web"), + + NATIVE("native"), + + CITRIX("citrix"), + + ONLINE_NATIVE("onlineNative"), + + OTHER("other"); + + private String value; + + Type(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static Type fromValue(String value) { + for (Type b : Type.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/WebAppDetails.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/WebAppDetails.java new file mode 100755 index 00000000..da800f50 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/model/WebAppDetails.java @@ -0,0 +1,88 @@ +package com.fdc.appd.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.constraints.NotNull; + +import java.util.Objects; + +/** + * Properties used to launch apps with `type: web`. + */ + +@Schema(name = "WebAppDetails", description = "Properties used to launch apps with `type: web`.") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-10T19:40:14.622447+05:30[Asia/Kolkata]", comments = "Generator version: 7.8.0") +public class WebAppDetails implements LaunchDetails { + + private String url; + + public WebAppDetails() { + super(); + } + + /** + * Constructor with only required parameters + */ + public WebAppDetails(String url) { + this.url = url; + } + + public WebAppDetails url(String url) { + this.url = url; + return this; + } + + /** + * Application start URL. + * @return url + */ + @NotNull + @Schema(name = "url", description = "Application start URL.", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("url") + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebAppDetails webAppDetails = (WebAppDetails) o; + return Objects.equals(this.url, webAppDetails.url); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WebAppDetails {\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtAuthInterceptor.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtAuthInterceptor.java new file mode 100755 index 00000000..ac72c880 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtAuthInterceptor.java @@ -0,0 +1,41 @@ +package com.fdc.appd.security; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@Component +public class JwtAuthInterceptor implements HandlerInterceptor { + + @Autowired + private UserManagementService userManagementService; + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String authHeader = request.getHeader("Authorization"); + + // Check if the Authorization header is present and starts with "Bearer " + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write("Missing or invalid Authorization header"); + return false; + } + + // Extract the token from the header + String token = authHeader.substring(7); + var claims = JwtUtil.validateToken(token); + + if (claims.isEmpty()) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write("Invalid or expired JWT token"); + return false; + } + + // Optionally, you can extract user information from the token and set it in the request context + request.setAttribute("userId", claims.get().getSubject()); + + return true; + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtUtil.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtUtil.java new file mode 100755 index 00000000..5fd3fc54 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/JwtUtil.java @@ -0,0 +1,42 @@ +package com.fdc.appd.security; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import java.security.Key; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JwtUtil { + + private static final Logger log = LoggerFactory.getLogger(JwtUtil.class); + + private static final String SECRET_KEY = "mIU3RoraRfc8TF3ScboaF8lcQF0nb5gb"; // Use a secure key in production! + + private static Key getSigningKey() { + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + + public static Optional validateToken(String token) { + try { + Claims claims = Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + + return Optional.of(claims); + } catch (Exception e) { + log.error("Invalid Tokenb", e); + throw new RuntimeException("Invalid token"); + } + } + + + public static String getUser(String token){ + Optional claims = validateToken(token.substring(7)); + Claims claim = claims.get(); + return String.valueOf(claim.get("name")); + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementService.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementService.java new file mode 100755 index 00000000..2fa0b24e --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementService.java @@ -0,0 +1,8 @@ +package com.fdc.appd.security; + +public interface UserManagementService { + + default public boolean validateUser(String userName) { + return false; + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementServiceImpl.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementServiceImpl.java new file mode 100755 index 00000000..955df678 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/UserManagementServiceImpl.java @@ -0,0 +1,40 @@ +package com.fdc.appd.security; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Objects; + +@Service +public class UserManagementServiceImpl implements UserManagementService { + + private static final Logger log = LoggerFactory.getLogger(UserManagementServiceImpl.class); + + HashMap userDb ; + @Override + public boolean validateUser(String userName) { + if(Objects.isNull(userDb)) + initializeUserDb(); + return userDb.containsKey(userName); + } + + private void initializeUserDb() { + this.userDb=new HashMap<>(); + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); + ClassPathResource resource = new ClassPathResource("user_db.json"); + + try { + userDb= objectMapper.readValue(resource.getInputStream(), new TypeReference>() {}); + } catch (IOException e) { + log.error("Error in loading the database", e); + } + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/WebConfig.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/WebConfig.java new file mode 100755 index 00000000..224bc1bd --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/security/WebConfig.java @@ -0,0 +1,18 @@ +package com.fdc.appd.security; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Autowired + private JwtAuthInterceptor jwtAuthInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(jwtAuthInterceptor); + } +} + diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/ApplicationReaderFactory.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/ApplicationReaderFactory.java new file mode 100755 index 00000000..b90d3aa8 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/ApplicationReaderFactory.java @@ -0,0 +1,32 @@ +package com.fdc.appd.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + + +/** + * This is the factory class which provides the V2ApplicationReader implementation based on the configuration (eg JSON , Database) + * Here in , a default implementation for the JSON datasource for App details JSON is provided . + */ +@Component +public class ApplicationReaderFactory { + + @Autowired + private V2ApplicationJsonReaderImpl v2ApplicationJsonReader; + + @Value("${fdc.application.readerType}") + private String readerType; + + /** + * Factory Method for creating the Application Details reader . + * @return + */ + public V2ApplicationReader createApplicationReader(){ + if(readerType.equalsIgnoreCase("JSON")){ + return v2ApplicationJsonReader; + } + else + throw new RuntimeException("No valid reader entry found"); + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationJsonReaderImpl.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationJsonReaderImpl.java new file mode 100755 index 00000000..00c74de3 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationJsonReaderImpl.java @@ -0,0 +1,87 @@ +package com.fdc.appd.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fdc.appd.datasources.JsonDatasourceConfig; +import com.fdc.appd.model.AllApplicationsResponse; +import com.fdc.appd.model.Application; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * This is the implementation for the reading the Application data from a JSON file. + */ +@Service +public class V2ApplicationJsonReaderImpl implements V2ApplicationReader{ + + @Autowired + JsonDatasourceConfig jsonDatasourceConfig; + + private List allApplications; + + + /** + * + * @param appId + * @return Application + * @throws IOException + */ + + @Override + public Application getApplication(String appId) throws IOException { + + if(Objects.isNull(allApplications)) + this.allApplications=readApplicationData(); + + return this.allApplications.stream().filter(application -> application.getAppId().equals(appId)).findFirst().orElseThrow(()-> new RuntimeException("Application Not found with the given appId")); + + } + + /** + * + * @return AppApplicationResponse + * @throws IOException + */ + @Override + public AllApplicationsResponse getAllApplication() throws IOException { + if(Objects.isNull(allApplications)) + this.allApplications=readApplicationData(); + AllApplicationsResponse response = new AllApplicationsResponse(); + response.setApplications(this.allApplications); + return response; + } + + /** + * + * @return List of from the Json + * @throws IOException + */ + private List readApplicationData() throws IOException { + + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); + ClassPathResource resource = new ClassPathResource(jsonDatasourceConfig.getPath()); + return objectMapper.readValue(resource.getInputStream(),AppJson.class).getApplications(); + + + } + + private static class AppJson{ + + List applications; + + public List getApplications() { + return applications; + } + + public void setApplications(List applications) { + this.applications = applications; + } + } + + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationReader.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationReader.java new file mode 100755 index 00000000..4b4e263d --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/java/com/fdc/appd/service/V2ApplicationReader.java @@ -0,0 +1,27 @@ +package com.fdc.appd.service; + +import com.fdc.appd.model.AllApplicationsResponse; +import com.fdc.appd.model.Application; + +import java.io.IOException; + + + + +public interface V2ApplicationReader { + + /** + * + * @param appId + * @return com.fdc.appd.model.Application + * @throws IOException + */ + public Application getApplication(String appId) throws IOException; + + /** + * + * @return com.fdc.appd.model.AllApplicationsResponse + * @throws IOException + */ + public AllApplicationsResponse getAllApplication() throws IOException; +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/app-directory-schema-2.0.yml b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/app-directory-schema-2.0.yml new file mode 100755 index 00000000..dfde67ec --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/app-directory-schema-2.0.yml @@ -0,0 +1,1255 @@ +openapi: 3.0.0 +info: + title: FDC3 Application Directory + version: 'next' + description: > + Application Directory specification providing both interface + definition and objects necessary to construct an application directory + service. + x-logo: + url: '/img/fdc3-logo-2019-color.png' + altText: FDC3 logo +security: +- bearerAuth: [] +paths: + '/v2/apps/{appId}': + get: + summary: Retrieve an application definition + parameters: + - name: appId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Application' + examples: + MyAppDefinition: + $ref: '#/components/examples/MyAppDefinition' + FDC3WorkbenchAppDefinition: + $ref: '#/components/examples/FDC3WorkbenchAppDefinition' + '400': + description: Bad request. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '403': + description: >- + Forbidden: Certificate authentication is not allowed for the + requested user. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '500': + description: 'Server error, see response body for further details.' + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + tags: + - Application + /v2/apps: + get: + summary: Retrieve all application definitions + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AllApplicationsResponse' + examples: + AllAppsResponse: + $ref: '#/components/examples/AllAppsResponse' + '400': + description: Bad request. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '403': + description: >- + Forbidden: Certificate authentication is not allowed for the + requested user. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '500': + description: 'Server error, see response body for further details.' + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + tags: + - Application + '/v1/apps/{appId}': + get: + deprecated: true + summary: Retrieve an application definition + parameters: + - name: appId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationV1' + '400': + description: Bad request. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '403': + description: >- + Forbidden: Certificate authentication is not allowed for the + requested user. + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + '500': + description: 'Server error, see response body for further details.' + content: + '*/*': + schema: + $ref: '#/components/schemas/ErrorDTO' + tags: + - Application + /v1/apps: + post: + deprecated: true + summary: Create a new application definition + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationSearchResponseV1' + '400': + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + '403': + description: >- + Forbidden: Certificate authentication is not allowed for the + requested user. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + '500': + description: 'Server error, see response body for further details.' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + tags: + - Application + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationV1' + required: true + /v1/apps/search: + get: + deprecated: true + summary: Retrieve a list of applications based on parameters provided. Depending on implementation, parameter + values should self describe search format and type (e.g. Regex) + parameters: + - in: query + name: appId + schema: + type: string + required: false + description: > + The unique application identifier located within a specific + application directory instance. + - in: query + name: name + schema: + type: string + required: false + description: > + The name of the application. + + The name should be unique within an FDC3 App Directory instance. The + exception to the uniqueness constraint is that an App Directory can + hold definitions for multiple versions of the same app. + + The same appName could occur in other directories. We are not + currently specifying app name conventions in the document. + - in: query + name: version + schema: + type: string + required: false + description: >- + Version of the application. This allows multiple app versions to be + defined using the same app name. This can be a triplet but can also + include things like 1.2.5 (BETA) + - in: query + name: title + schema: + type: string + required: false + description: >- + Optional title for the application, if missing use appName, + typically used in a launcher UI. + - in: query + name: tooltip + schema: + type: string + required: false + description: Optional tooltip description e.g. for a launcher + - in: query + name: description + schema: + type: string + required: false + description: >- + Description of the application. This will typically be a 1-2 + paragraph style blurb about the application. Allow mark up language + - in: query + name: intent_name + schema: + type: string + required: false + description: name of intent + - in: query + name: intent_displayName + schema: + type: string + required: false + description: displayName of intent + - in: query + name: intent_context + schema: + type: string + required: false + description: search contexts list + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationSearchResponseV1' + '400': + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + '403': + description: >- + Forbidden: Certificate authentication is not allowed for the + requested user. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + '500': + description: 'Server error, see response body for further details.' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDTO' + tags: + - Application + +servers: + - url: /appd +components: + securitySchemes: + bearerAuth: # arbitrary name for the security scheme + type: http + scheme: bearer + bearerFormat: JWT # optional, arbitrary value for documentation purposes + schemas: + ErrorDTO: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + BaseApplication: + properties: + appId: + type: string + description: > + The unique application identifier located within a specific + application directory instance. + name: + type: string + description: > + The name of the application. + + The name should be unique within an FDC3 App Directory instance. The + exception to the uniqueness constraint is that an App Directory can + hold definitions for multiple versions of the same app. + + The same appName could occur in other directories. We are not + currently specifying app name conventions in the document. + type: + $ref: '#/components/schemas/Type' + details: + $ref: '#/components/schemas/LaunchDetails' + version: + type: string + description: >- + Version of the application. This allows multiple app versions to be + defined using the same app name. This can be a triplet but can also + include things like 1.2.5 (BETA) + title: + type: string + description: >- + Optional title for the application, if missing use appName, + typically used in a launcher UI. + tooltip: + type: string + description: Optional tooltip description e.g. for a launcher + lang: + type: string + pattern: '^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$' + description: >- + A language tag that specifies the primary language of both the + application and its AppD entry, as defined by IETF RFC 5646. + description: + type: string + description: >- + Description of the application. This will typically be a 1-2 + paragraph style blurb about the application. + categories: + description: | + An array of string categories that describe the application. + These are meant as a hint to catalogs or stores listing FDC3-enabled + apps and it is expected that these will make a best effort to find + appropriate categories (or category) under which to list the app. + AppD record authors are encouraged to use lower-case and, where + possible, to select categories from the following list: + + - allocations + - analytics + - charts + - chat + - communication + - compliance + - crm + - developer tools + - events + - execution management + - file sharing + - market data + - news + - networking + - office apps + - order management + - other + - portfolio management + - presentation + - pricing + - productivity + - research + - risk + - screen sharing + - security + - spreadsheet + - trade cost analysis + - trading system + - training + - travel + - video + - visualisation + - weather + type: array + items: + type: string + icons: + type: array + description: >- + Holds Icons used for the application, a Launcher may be able to use + multiple Icon sizes or there may be a 'button' Icon + items: + $ref: '#/components/schemas/Icon' + screenshots: + type: array + description: >- + Array of images to show the user when they are looking at app + description. Each image can have an optional description/tooltip + items: + $ref: '#/components/schemas/Screenshot' + contactEmail: + type: string + format: email + description: Optional e-mail to receive queries about the application + supportEmail: + type: string + format: email + description: Optional e-mail to receive support requests for the application + moreInfo: + type: string + format: uri + description: Optional URL that provides more infomation about the application + publisher: + type: string + description: >- + The name of the company that owns the application. The publisher has + control over their namespace/app/signature. + customConfig: + type: array + description: >- + An optional set of name value pairs that can be used to deliver + custom data from an App Directory to a launcher. + items: + $ref: '#/components/schemas/NameValuePair' + hostManifests: + $ref: '#/components/schemas/HostManifests' + interop: + $ref: '#/components/schemas/Interop' + Application: + description: > + Defines an application retrieved from an FDC3 App Directory, which can + then be launched. + + Launching typically means running for a user on a desktop. + The details around 'launching' including who or what might do it, and how the launch action is initiated are + discussed elsewhere in the FDC3 App Directory spec. + required: + - appId + - name + - type + - details + allOf: + - $ref: '#/components/schemas/BaseApplication' + - type: object + properties: + localizedVersions: + $ref: '#/components/schemas/LocalizedVersions' + AllApplicationsResponse: + properties: + applications: + type: array + description: | + List of applications + items: + $ref: '#/components/schemas/Application' + message: + type: string + description: | + Response message providing status of query + NameValuePair: + description: Simple name value pair + properties: + name: + type: string + description: name + value: + type: string + description: value + Icon: + description: Icon holder + properties: + src: + type: string + format: uri + description: Icon URL + size: + type: string + description: Icon dimension formatted as `x` + type: + type: string + description: Image media type. If not present the Desktop Agent may use the src file extension + Screenshot: + description: Images representing the app in common usage scenarios + properties: + src: + type: string + format: uri + description: App Image URL + size: + type: string + description: Image dimension formatted as `x` + type: + type: string + description: Image media type. If not present the Desktop Agent may use the src file extension. + label: + type: string + description: Optional caption for the image + Type: + type: string + description: | + The technology type that is used to launch and run the application. + Each application type implies a particular set of launch `details`. + The supported types include: + + - `web`: Web applications launched via a URL + - `native`: Native applications pre-installed on a device and launch via a filesystem path + - `citrix`: Apps virtualized via Citrix + - `onlineNative`: Native apps that have an online launcher, e.g. online ClickOnce app deployments. + - `other`: Used to represent apps that do not conform to or cannot be launched via the other types, and are likely to be defined solely by a hostManifest. + + FDC3 Desktop Agents MUST support at least the `web` application type and MAY support any or all of the other types. + enum: + - web + - native + - citrix + - onlineNative + - other + LaunchDetails: + description: >- + The type specific launch details of the application. These details are intended to be + vendor-agnostic and MAY be duplicated or overridden by details provided in the hostManifests + object for a specific host. + oneOf: + - $ref: '#/components/schemas/WebAppDetails' + - $ref: '#/components/schemas/NativeAppDetails' + - $ref: '#/components/schemas/CitrixAppDetails' + - $ref: '#/components/schemas/OnlineNativeAppDetails' + - $ref: '#/components/schemas/OtherAppDetails' + WebAppDetails: + description: 'Properties used to launch apps with `type: web`.' + required: + - url + properties: + url: + type: string + #formt: uri + description: Application start URL. + additionalProperties: false + NativeAppDetails: + description: 'Properties used to launch apps with `type: native` that are already installed on the device.' + required: + - path + properties: + path: + type: string + description: The path on disk from which the application is launched. + arguments: + type: string + description: Arguments that must be passed on the command line to launch the app in the expected configuration. + additionalProperties: false + CitrixAppDetails: + description: 'Properties used to launch apps virtualized apps with `type: citrix`.' + required: + - alias + properties: + alias: + type: string + description: The Citrix alias / name of the virtual app (passed to the Citrix SelfService qlaunch parameter). + arguments: + type: string + description: Arguments that must be passed on the command line to launch the app in the expected configuration. + additionalProperties: false + OnlineNativeAppDetails: + description: 'Properties used to launch a native apps with `type: onlineNative` that have an online launcher, e.g. online ClickOnce app deployments.' + required: + - url + properties: + url: + type: string + format: uri + description: Application URL. + additionalProperties: false + OtherAppDetails: + description: 'Apps with `type: other` are defined by a hostManifest and do not require other details.' + additionalProperties: false + HostManifests: + type: object + description: >- + A mapping from host name to a host-specific application manifest object or URI + from which that manifest can be retrieved. The manifest should provide details required to + launch and use the application within the specified host. The manifest _MAY_ duplicate or + override information provided in the `details` field. + additionalProperties: + x-additionalPropertiesName: Host name + oneOf: + - type: string # URI pointing to a JSON containing all host specific properties + format: uri + - $ref: '#/components/schemas/HostManifest' + HostManifest: + type: object + description: >- + Object containing all host specific properties. + LocalizedVersions: + type: object # keys should be constrained to valid language tags '^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$' - not possible to express in OpenAPI without moving to v3.1.0 and the javascript/jsonschema version + description: > + Provides localized alternatives to any field of the AppD record, which may also refer to an alternative + version of the application that is also localized (e.g. by providing customConfig or an alternative URL). + The keys to this object should be language tags as defined by IETF RFC 5646, e.g. en, en-GB or fr-FR. + additionalProperties: + x-additionalPropertiesName: Language tag + $ref: '#/components/schemas/BaseApplication' # due to a bug in redoc this may display as a recursive definition, it is not. It will render correctly in swagger and other OpenAPI parsers. + Intent: + description: >- + Definition of an intent that an app listens for + required: + - contexts + properties: + displayName: + type: string + description: An optional display name for the intent that may be used in UI instead of the name. + contexts: + type: array + items: + type: string + description: >- + A comma separated list of the types of contexts the intent offered by the application can process, + where the first part of the context type is the namespace e.g."fdc3.contact, org.symphony.contact" + resultType: + type: string + description: >- + An optional type for output returned by the application, if any, when resolving this intent. + May indicate a context type by type name (e.g. "fdc3.instrument"), a channel (e.g. "channel") + or a combination that indicates a channel that returns a particular context type + (e.g. "channel"). + customConfig: + type: object + description: >- + Custom configuration for the intent that may be required for a + particular desktop agent. + Interop: + type: object + description: | + Metadata that describes how the application uses FDC3 APIs. This metadata serves multiple purposes: + + - It supports intent resolution by a desktop agent, by declaring what intents an app listens for. + - It may be used, for example in an app catalog UI, to find apps that 'interoperate with' other apps. + - It provides a standard location to document how the app interacts with user channels, app channels, + and intents, for use by other app developers and desktop assemblers. + properties: + intents: + type: object + description: Describes the app's interactions with intents. + properties: + listensFor: + type: object + description: | + A mapping of Intents names that an app listens for via `fdc3.addIntentListener()` to their + configuration. + + Used to support intent resolution by desktop agents. Replaces the `intents` element used in appD records prior to FDC3 2.0. + additionalProperties: + x-additionalPropertiesName: Intent name + $ref: '#/components/schemas/Intent' + raises: + type: object + description: | + A mapping of Intent names that an app raises (via `fdc3.raiseIntent`) to an array of context + type names that it may be raised with. + + Use the intent name "any" to represent use of the `fdc3.raiseIntentForContext` and + `fdc3.findIntentForContext` functions, which allow the user to select from intents available for a + specified context type. + + This metadata is not currently used by the desktop agent, but is provided to help find apps + that will interoperate with this app and to document API interactions for use by other app + developers. + additionalProperties: + x-additionalPropertiesName: Intent name + type: array + description: Context type names that the intent may be raised with. + items: + type: string + userChannels: + type: object + description: | + Describes the application's use of context types on User Channels. + + This metadata is not currently used by the desktop agent, but is provided to help find apps + that will interoperate with this app and to document API interactions for use by other app + developers. + properties: + broadcasts: + type: array + description: Context type names that are broadcast by the application. + items: + type: string + listensFor: + type: array + description: Context type names that the application listens for. + items: + type: string + appChannels: + type: array + description: | + Describes the application's use of App Channels. + + This metadata is not currently used by the desktop agent, but is provided to help find apps + that will interoperate with this app and to document API interactions for use by other app + developers. + items: + type: object + required: + - name + properties: + name: + type: string + description: The name of the App Channel. + description: + type: string + description: A description of how the channel is used. + broadcasts: + type: array + description: Context type names that are broadcast by the application on the channel. + items: + type: string + listensFor: + type: array + description: Context type names that the application listens for on the channel. + items: + type: string + AppImageV1: + description: App Image holder + properties: + url: + type: string + format: uri + description: App Image URL + IconV1: + description: (Deprecated v1 API version) Icon holder + properties: + icon: + type: string + format: uri + description: Icon URL + IntentV1: + description: >- + (Deprecated v1 API version) An intent definition as defined by spec + https://github.com/FDC3/Intents/blob/master/src/Intent.yaml + required: + - name + properties: + name: + type: string + description: The name of the intent to 'launch'. In this case the name of an Intent supported by an application. + displayName: + type: string + description: An optional display name for the intent that may be used in UI instead of the name. + contexts: + type: array + items: + type: string + description: >- + A comma sepaarted list of the types of contexts the intent offered by the application can process. + where the first part of the context type is the namespace e.g."fdc3.contact, org.symphony.contact" + customConfig: + type: object + description: >- + Custom configuration for the intent that may be required for a + particular desktop agent. + ApplicationV1: + description: > + (Deprecated v1 API version) Defines an application retrieved from an FDC3 App Directory, which can + then be launched. + Launching typically means running for a user on a desktop. + The details around 'launching' including who or what might do it, and how the launch action is initiated are + discussed elsewhere in the FDC3 App Directory spec. + required: + - appId + - name + - manifest + - manifestType + properties: + appId: + type: string + description: > + The unique application identifier located within a specific + application directory instance. + name: + type: string + description: > + The name of the application. + The name should be unique within an FDC3 App Directory instance. The + exception to the uniqueness constraint is that an App Directory can + hold definitions for multiple versions of the same app. + The same appName could occur in other directories. We are not + currently specifying app name conventions in the document. + manifest: + type: string + description: > + URI or full JSON of the application manifest providing all details related to launch + and use requirements as described by the vendor. + The format of this manifest is vendor specific, but can be identified by + the manifestType attribute. + manifestType: + type: string + description: > + The manifest type which relates to the format and structure of the manifest content. + The definition is based on the vendor specific format and definition outside of this specification. + version: + type: string + description: >- + Version of the application. This allows multiple app versions to be + defined using the same app name. This can be a triplet but can also + include things like 1.2.5 (BETA) + title: + type: string + description: >- + Optional title for the application, if missing use appName, + typically used in a launcher UI. + tooltip: + type: string + description: Optional tooltip description e.g. for a launcher + description: + type: string + description: >- + Description of the application. This will typically be a 1-2 + paragraph style blurb about the application. Allow mark up language + images: + type: array + description: >- + Array of images to show the user when they are looking at app + description. Each image can have an optional description/tooltip + items: + $ref: '#/components/schemas/AppImageV1' + contactEmail: + type: string + format: email + description: Optional e-mail to receive queries about the application + supportEmail: + type: string + format: email + description: Optional e-mail to receive support requests for the application + publisher: + type: string + description: >- + The name of the company that owns the application. The publisher has + control over their namespace/app/signature. + icons: + type: array + description: >- + Holds Icons used for the application, a Launcher may be able to use + multiple Icon sizes or there may be a 'button' Icon + items: + $ref: '#/components/schemas/IconV1' + customConfig: + type: array + description: >- + An optional set of name value pairs that can be used to deliver + custom data from an App Directory to a launcher. + items: + $ref: '#/components/schemas/NameValuePair' + intents: + type: array + description: > + The list of intents implemented by the application as defined by + https://github.com/FDC3/Intents/blob/master/src/Intent.yaml + items: + $ref: '#/components/schemas/IntentV1' + ApplicationSearchResponseV1: + properties: + applications: + type: array + description: | + List of applications + items: + $ref: '#/components/schemas/ApplicationV1' + message: + type: string + description: | + Response message providing status of query + examples: + FDC3WorkbenchAppDefinition: + value: + appId: fdc3-workbench + name: fdc3-workbench + title: FDC3 Workbench + description: Development and test tool for FDC3 desktop agents and apps + categories: [developer tools, training] + version: 1.0.0 + tooltip: FDC3 Workbench + lang: en-US + icons: + - src: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png + screenshots: + - src: https://fdc3.finos.org/docs/assets/fdc3-logo.png + label: FDC3 logo + contactEmail: fdc3@finos.org + supportEmail: fdc3-maintainers@finos.org + moreInfo: https://fdc3.finos.org #update to point to implementations page when it exists + publisher: FDC3 + type: web + details: + url: https://fdc3.finos.org/toolbox/fdc3-workbench/ + hostManifests: { + Glue42: { + type: window, + icon: https://fdc3.finos.org/docs/assets/fdc3-logo.png, + details: { + height: 640, + width: 560, + left: 120, + top: 120, + mode: tab, + allowChannels: true, + loader: { + enabled: true, + hideOnLoad: true + } + }, + customProperties: { + folder: FDC3 Toolbox + } + }, + Finsemble: { + window: { + left: 120, + top: 120, + width: 800, + height: 750, + options: { + minWidth: 75 + } + }, + foreign: { + components: { + App Launcher: { + launchableByUser: true + }, + Toolbar: { + iconURL: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png + }, + Window Manager: { + FSBLHeader: true, + persistWindowState: true + } + } + }, + interop: { + autoConnect: true + } + }, + Web App Manifest: https://example.com/fdc3-workbench.json + } + localizedVersions: { + fr-FR: { + title: FDC3 Table de travail, + description: Outil de développement et de test pour les desktop agents et applications FDC3 + } + } + summary: A sample app definition for the FDC3 Workbench application + MyAppDefinition: + value: + appId: my-application + name: my-application + title: My Application + description: An example application that uses FDC3 and fully describes itself in an AppD record. + categories: [market data, research, news] + version: 1.0.0 + tooltip: My example application definition + lang: en-US + icons: + - src: http://example.domain.com/assets/my-app-icon.png + size: 256x256 + type: image/png + screenshots: + - src: http://example.domain.com/assets/my-app-screenshot-1.png + label: The first screenshot of my example app + type: image/png + size: 800x600 + - src: http://example.domain.com/assets/my-app-screenshot-2.png + label: The second screenshot of my example app + type: image/png + size: 800x600 + contactEmail: fdc3@finos.org + supportEmail: fdc3-maintainers@finos.org + moreInfo: http://example.domain.com/ + publisher: Example App, Inc. + type: web + details: + url: http://example.domain.com/app.html + hostManifests: { + Finsemble: { + window: { + left: 120, + top: 120, + width: 600, + height: 800, + options: { + minWidth: 75 + } + }, + foreign: { + components: { + App Launcher: { + launchableByUser: true + }, + Window Manager: { + FSBLHeader: true, + persistWindowState: true + } + } + }, + interop: { + autoConnect: true + } + }, + Glue42: { + type: window, + details: { + height: 800, + width: 600, + left: 120, + top: 120, + mode: tab, + allowChannels: true, + loader: { + enabled: true, + hideOnLoad: true + } + }, + customProperties: { + folder: FDC3 Toolbox + } + }, + Web App Manifest: http://example.domain.com/my-app.json + } + interop: + intents: + listensFor: + ViewChart: + displayName: View Chart + contexts: + - fdc3.instrument + myApp.GetPrice: + displayName: Get Price + contexts: + - fdc3.instrument + resultType: myApp.quote + raises: + ViewOrders: + - fdc3.instrument + - fdc3.organization + StartEmail: + - fdc3.email + userChannels: + broadcasts: + - fdc3.instrument + - fdc3.organization + listensFor: + - fdc3.instrument + - fdc3.organization + appChannels: + - name: myApp.quotes, + description: >- + Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol, + broadcasts: + - myApp.quote + listensFor: + - fdc3.instrument + localizedVersions: + fr-FR: + title: Mon application, + description: Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD. + summary: A sample app definition for an application that describes its use of interop. + AllAppsResponse: + value: + applications: # you can't $ref inside a $ref so example is repeated here for search response + - appId: my-application + name: my-application + title: My Application + description: An example application that uses FDC3 and fully describes itself in an AppD record. + categories: [market data, research, news] + version: 1.0.0 + tooltip: My example application definition + lang: en-US + icons: + - src: http://example.domain.com/assets/my-app-icon.png + size: 256x256 + type: image/png + screenshots: + - src: http://example.domain.com/assets/my-app-screenshot-1.png + label: The first screenshot of my example app + type: image/png + size: 800x600 + - src: http://example.domain.com/assets/my-app-screenshot-2.png + label: The second screenshot of my example app + type: image/png + size: 800x600 + contactEmail: fdc3@finos.org + supportEmail: fdc3-maintainers@finos.org + moreInfo: http://example.domain.com/ + publisher: Example App, Inc. + type: web + details: + url: http://example.domain.com/app.html + hostManifests: { + Finsemble: { + window: { + left: 120, + top: 120, + width: 600, + height: 800, + options: { + minWidth: 75 + } + }, + foreign: { + components: { + App Launcher: { + launchableByUser: true + }, + Window Manager: { + FSBLHeader: true, + persistWindowState: true + } + } + }, + interop: { + autoConnect: true + } + }, + Glue42: { + type: window, + details: { + height: 800, + width: 600, + left: 120, + top: 120, + mode: tab, + allowChannels: true, + loader: { + enabled: true, + hideOnLoad: true + } + }, + customProperties: { + folder: FDC3 Toolbox + } + }, + Web App Manifest: http://example.domain.com/my-app.json + } + interop: + intents: + listensFor: + ViewChart: + displayName: View Chart + contexts: + - fdc3.instrument + myApp.GetPrice: + displayName: Get Price + contexts: + - fdc3.instrument + resultType: myApp.quote + raises: + ViewOrders: + - fdc3.instrument + - fdc3.organization + StartEmail: + - fdc3.email + userChannels: + broadcasts: + - fdc3.instrument + - fdc3.organization + listensFor: + - fdc3.instrument + - fdc3.organization + appChannels: + - name: myApp.quotes, + description: >- + Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol, + broadcasts: + - myApp.quote + listensFor: + - fdc3.instrument + localizedVersions: + fr-FR: + title: Mon application, + description: Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD. + - appId: fdc3-workbench + name: fdc3-workbench + title: FDC3 Workbench + description: Development and test tool for FDC3 desktop agents and apps + categories: [developer tools, training] + version: 1.0.0 + tooltip: FDC3 Workbench + lang: en-US + icons: + - src: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png + screenshots: + - src: https://fdc3.finos.org/docs/assets/fdc3-logo.png, + label: FDC3 logo + contactEmail: fdc3@finos.org, + supportEmail: fdc3-maintainers@finos.org, + publisher: FDC3, + type: web + details: + url: https://fdc3.finos.org/toolbox/fdc3-workbench/ + hostManifests: { + Glue42: { + type: window, + icon: https://fdc3.finos.org/docs/assets/fdc3-logo.png, + details: { + height: 640, + width: 560, + left: 120, + top: 120, + mode: tab, + allowChannels: true, + loader: { + enabled: true, + hideOnLoad: true + } + }, + customProperties: { + folder: FDC3 Toolbox + } + }, + Finsemble: { + window: { + left: 120, + top: 120, + width: 800, + height: 750, + options: { + minWidth: 75 + } + }, + foreign: { + components: { + App Launcher: { + launchableByUser: true + }, + Toolbar: { + iconURL: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png + }, + Window Manager: { + FSBLHeader: true, + persistWindowState: true + } + } + }, + interop: { + autoConnect: true + } + }, + Web App Manifest: https://example.com/fdc3-workbench.json + } + localizedVersions: { + fr-FR: { + title: FDC3 Table de travail, + description: Outil de développement et de test pour les desktop agents et applications FDC3 + } + } + message: OK + summary: A sample 'all applications' listing response diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/application.properties b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/application.properties new file mode 100755 index 00000000..c571925a --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/application.properties @@ -0,0 +1,7 @@ +spring.application.name=fdc3-app-directory-java-spring +fdc.appd.app-json.path=local.v2.json + +spring.security.user.name=sa +spring.security.user.password-sa + +fdc.application.readerType=JSON \ No newline at end of file diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/local.v2.json b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/local.v2.json new file mode 100755 index 00000000..bd8985ae --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/local.v2.json @@ -0,0 +1,871 @@ +{ + "applications": [ + { + "appId": "ChannelsAppId", + "name": "ChannelsApp", + "title": "Channels App", + "description": "Part of the FDC3 1.2 Conformance Tests", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/channels/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/Channels/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Channels App" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Intent App B" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ] + }, + { + "appId": "Conformance1", + "name": "Conformance1", + "title": "FDC3 1.2 Conformance Framework", + "description": "Testing Conformance", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/app/" + }, + "screenshots": [ + { + "src": "https://directory.fdc3.finos.org/assets/app/Conformance1.png" + } + ], + "hostManifests": { + "sail": { + "injectApi": "1.2" + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/app/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": true, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ] + }, + { + "appId": "IntentAppAId", + "name": "IntentAppA", + "title": "Intent App A", + "description": "Part of the FDC3 1.2 Conformance Tests", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-a/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-a/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Intent App A" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Intent App A" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ], + "interop": { + "intents": { + "listensFor": { + "aTestingIntent": { + "displayName": "A Testing Intent", + "contexts": [ + "testContextX", + "testContextZ" + ] + }, + "sharedTestingIntent1": { + "displayName": "Shared Testing Intent", + "contexts": [ + "testContextX" + ] + } + } + } + } + }, + { + "appId": "IntentAppBId", + "name": "IntentAppB", + "title": "Intent App B", + "description": "Part of the FDC3 1.2 Conformance Tests", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-b/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-b/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Intent App B" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Intent App B" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ], + "interop": { + "intents": { + "listensFor": { + "bTestingIntent": { + "displayName": "B Testing Intent", + "contexts": [ + "testContextY" + ] + }, + "sharedTestingIntent1": { + "displayName": "Shared Testing Intent", + "contexts": [ + "testContextX", + "testContextY" + ] + } + } + } + } + }, + { + "appId": "IntentAppCId", + "name": "IntentAppC", + "title": "Intent App C", + "description": "Part of the FDC3 1.2 Conformance Tests", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-c/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/intent-c/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Intent App C" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Intent App B" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ], + "interop": { + "intents": { + "listensFor": { + "cTestingIntent": { + "displayName": "C Testing Intent", + "contexts": [ + "testContextX" + ] + } + } + } + } + }, + { + "appId": "MockAppId", + "name": "MockApp", + "description": "Testing spec conformance", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/general/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/general/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Mock App" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Mock App" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ] + }, + { + "appId": "fdc3-workbench", + "name": "fdc3-workbench", + "title": "FDC3 Workbench", + "description": "Development and test tool for FDC3 desktop agents and apps", + "categories": [ + "developer tools", + "training" + ], + "version": "1.0.0", + "tooltip": "FDC3 Workbench", + "lang": "en-US", + "icons": [ + { + "src": "https://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + } + ], + "screenshots": [ + { + "src": "https://fdc3.finos.org/docs/assets/fdc3-logo.png", + "label": "FDC3 logo" + } + ], + "contactEmail": "fdc3@finos.org,", + "supportEmail": "fdc3-maintainers@finos.org,", + "publisher": "FDC3", + "type": "web", + "details": { + "url": "https://fdc3.finos.org/toolbox/fdc3-workbench/" + }, + "hostManifests": { + "Glue42": { + "type": "window", + "icon": "https://fdc3.finos.org/docs/assets/fdc3-logo.png", + "details": { + "height": 640, + "width": 560, + "left": 120, + "top": 120, + "mode": "tab", + "allowChannels": true, + "loader": { + "enabled": true, + "hideOnLoad": true + } + }, + "customProperties": { + "folder": "FDC3 Toolbox" + } + }, + "Finsemble": { + "window": { + "left": 120, + "top": 120, + "width": 800, + "height": 750, + "options": { + "minWidth": 75 + } + }, + "foreign": { + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Toolbar": { + "iconURL": "http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + }, + "Window Manager": { + "FSBLHeader": true, + "persistWindowState": true + } + } + }, + "interop": { + "autoConnect": true + } + }, + "Web App Manifest": "https://example.com/fdc3-workbench.json" + }, + "localizedVersions": { + "fr-FR": { + "title": "FDC3 Table de travail", + "description": "Outil de développement et de test pour les desktop agents et applications FDC3" + } + } + }, + { + "appId": "symphony", + "categories": [ + "chat", + "communication", + "compliance", + "productivity" + ], + "contactEmail": "sales@symphony.com", + "description": "Symphony is the most secure and compliance-enabling markets’ infrastructure and technology platform, where solutions are built or integrated to standardize, automate and innovate financial services workflows. It is a vibrant community of over half a million financial professionals with a trusted directory and serves over 1,000 institutions.", + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/symphonyChat/index.html" + }, + "icons": [ + { + "src": "https://fdc3.finos.org/img/users/Symphony.png" + } + ], + "interop": { + "intents": { + "listensFor": { + "SendChatMessage": { + "contexts": [ + "fdc3.chat.message" + ], + "displayName": "Send Chat Message" + }, + "StartChat": { + "contexts": [ + "fdc3.contact", + "fdc3.contactList", + "fdc3.chat.initSettings" + ], + "displayName": "Start Chat" + }, + "ViewMessages": { + "contexts": [ + "fdc3.searchCriteria" + ], + "displayName": "View Messages" + } + }, + "raises": { + "CreateInteraction": { + "contexts": [ + "fdc3.interaction" + ], + "displayName": "Create Interaction" + }, + "ViewContact": { + "contexts": [ + "fdc3.contact" + ], + "displayName": "View Contact" + } + } + } + }, + "moreInfo": "https://symphony.com/", + "name": "Symphony", + "publisher": "Symphony Communication Services, LLC", + "screenshots": [ + { + "src": "https://symphony.com/wp-content/uploads/2021/09/SYM-Hero-with-C9-1-2048x1688.png" + } + ], + "hostManifests": { + "sail": { + "injectApi": "2.0", + "framesApi": true + } + }, + "supportEmail": "support@symphony.com", + "title": "Symphony" + }, + { + "appId": "tickerDetails", + "name": "tickerDetails", + "title": "Ticker Details Demo", + "description": "A demo of ticker detail information, using data from Polygon.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tickerDetails/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tickerDetails/screenshot.png", + "label": "Screenshot 1" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tickerDetails.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewInstrument": { + "displayName": "View Instrument", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "1.2" + } + } + }, + { + "appId": "newsAPI", + "name": "newsAPI", + "title": "News API", + "description": "A demo app using the NewsAPI service to provide basic news search based on a ticker.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/newsAPI/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/newsAPI/screenshot.png", + "label": "Demo Screenshot" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/newsAPI.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewNews": { + "displayName": "View News", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tickerGrid", + "name": "tickerGrid", + "title": "Ticker Grid", + "description": "A demo app of a grid display of companies as a starting of point for FDC3 functionality.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tickerGrid/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tickerGrid/screenshot.png", + "label": "Demo Screenshot" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tickerGrid.html" + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tradingviewChart", + "name": "tradingviewChart", + "title": "TradingView Chart", + "description": "A demo app for FDC3 using a charting widget from TradingView.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewChart/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewChart/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tradingviewChart.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewChart": { + "displayName": "View Chart", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tickerChart", + "name": "tickerChart", + "title": "Ticker Chart", + "description": "A demo charting app for FDC3, using data from Polygon.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tickerChart/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tickerChart/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tickerChart.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewChart": { + "displayName": "View Chart", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tradingviewBlotter", + "name": "tradingviewBlotter", + "title": "TradingView Blotter", + "description": "A demo app for FDC3 using widgets from TradingView.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewBlotter/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewBlotter/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tradingviewBlotter.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewQuote": { + "displayName": "View Quote", + "contexts": [ + "fdc3.instrument" + ] + } + }, + "ViewInstrument": { + "displayName": "View Instrument", + "contexts": [ + "fdc3.instrument" + ] + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tickerPrevClose", + "name": "tickerPrevClose", + "title": "Ticker Previous Close", + "description": "A snapshot of the pricing data for the ticker - going by previous market close, using data from Polygon.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tickerPrevClose/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tickerPrevClose/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tickerPrevClose.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewQuote": { + "displayName": "View Quote", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + } + ] +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/user_db.json b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/user_db.json new file mode 100755 index 00000000..11c86338 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/main/resources/user_db.json @@ -0,0 +1,5 @@ + + { + "alice": "portfolio-manager", + "bob":"equity-sell-trader" + } \ No newline at end of file diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplicationTests.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplicationTests.java new file mode 100755 index 00000000..5bb601e9 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/Fdc3AppDirectoryJavaSpringApplicationTests.java @@ -0,0 +1,10 @@ +package com.fdc.appd; + +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class Fdc3AppDirectoryJavaSpringApplicationTests { + + + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/V2ApiDelegateImplTests.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/V2ApiDelegateImplTests.java new file mode 100644 index 00000000..5fcf234c --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/V2ApiDelegateImplTests.java @@ -0,0 +1,126 @@ +package com.fdc.appd; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito.*; + +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.*; +import com.fdc.appd.model.*; +import com.fdc.appd.security.UserManagementService; +import com.fdc.appd.service.ApplicationReaderFactory; +import com.fdc.appd.service.V2ApplicationJsonReaderImpl; +import com.fdc.appd.service.V2ApplicationReader; + + +@ExtendWith(MockitoExtension.class) +public class V2ApiDelegateImplTests { + + + @Mock + UserManagementService userManagementService; + + @Mock + ApplicationReaderFactory readerFactory; + + V2ApplicationReader applicationReader; + + @InjectMocks + private V2ApiDelegateImpl v2ApiDelegateImpl; + + @BeforeEach // For JUnit 5 + // @Before // For JUnit 4 + public void setup() { + MockitoAnnotations.openMocks(this); // Initialize mocks + applicationReader = Mockito.mock(V2ApplicationJsonReaderImpl.class); + + when(readerFactory.createApplicationReader()).thenReturn(applicationReader); + Mockito.when(userManagementService.validateUser(Mockito.anyString())).thenReturn(true); + } + + String alice="Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.As-48YMQrjkiEoPTj7COq9LoCEQsZn8IfCOPA0a-psI"; + + @Test + void testV2AppsAppIdGetSuccess() { + + Application application = applications().stream().filter(x -> x.getAppId().equals("APP_ID_1")).findFirst().get(); + try { + Mockito.when(applicationReader.getApplication(Mockito.anyString())).thenReturn(application); + ResponseEntity response = v2ApiDelegateImpl.v2AppsAppIdGet("APP_ID_1", alice); + System.out.println(response); + assertEquals("app1", response.getBody().getName()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Test + void testV2AppsAppIdGetFail() { + + assertThrows(RuntimeException.class, ()->{ + Mockito.when(applicationReader.getApplication(Mockito.anyString())).thenThrow(new IOException()); + ResponseEntity response = v2ApiDelegateImpl.v2AppsAppIdGet("APP_ID_2", alice); + System.out.println(response); + assertEquals("app1", response.getBody().getName()); + + }); + } + + @Test + void testV2AppsAppIdGetAppNotFound() { + + assertThrows(RuntimeException.class, ()->{ + Mockito.when(applicationReader.getApplication(Mockito.anyString())).thenThrow(new RuntimeException("Application Not found with the given appId\"")); + ResponseEntity response = v2ApiDelegateImpl.v2AppsAppIdGet("APP_ID_2", alice); + System.out.println(response); + assertEquals("app1", response.getBody().getName()); + + }); + } + + @Test + void testV2AppsGet() { + + try { + AllApplicationsResponse allApplicationsResponse = new AllApplicationsResponse(); + allApplicationsResponse.applications(applications()); + Mockito.when(applicationReader.getAllApplication()).thenReturn(allApplicationsResponse); + ResponseEntity response = v2ApiDelegateImpl.v2AppsGet(alice); + System.out.println(response); + assertEquals(applications().size(), response.getBody().getApplications().size()); + } catch (IOException e) { + + e.printStackTrace(); + } + + + } + + private List applications(){ + Application application = new Application(); + application.setAppId("APP_ID_1"); + application.setName("app1"); + + Application application2 = new Application(); + application2.setAppId("APP_ID_2"); + application2.setName("app2"); + List list = new LinkedList<>(); + list.add(application2); + list.add(application); + return list; + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/ApplicationReaderFactoryTest.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/ApplicationReaderFactoryTest.java new file mode 100644 index 00000000..334c45dc --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/ApplicationReaderFactoryTest.java @@ -0,0 +1,45 @@ +package com.fdc.appd.service; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.util.ReflectionTestUtils; + +public class ApplicationReaderFactoryTest { + + @Mock + private V2ApplicationJsonReaderImpl v2ApplicationJsonReader; + + @InjectMocks + public ApplicationReaderFactory applicationReaderFactory; + + @BeforeEach + public void setup() { + MockitoAnnotations.openMocks(this); // Initialize mocks + + + } + + @Test + void testCreateApplicationReader() { + ReflectionTestUtils.setField(applicationReaderFactory, "readerType", "JSON"); + assertEquals(applicationReaderFactory.createApplicationReader(),v2ApplicationJsonReader); + } + + @Test + void testCreateApplicationReaderFailure() { + RuntimeException returnValue = assertThrows(RuntimeException.class, ()->{ + ReflectionTestUtils.setField(applicationReaderFactory, "readerType", "JSONB"); + assertEquals(applicationReaderFactory.createApplicationReader(),v2ApplicationJsonReader); + }); + + assertEquals("No valid reader entry found", returnValue.getMessage()); + } + + +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/V2ApplicationJsonReaderImplTest.java b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/V2ApplicationJsonReaderImplTest.java new file mode 100644 index 00000000..1ff94cfb --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/java/com/fdc/appd/service/V2ApplicationJsonReaderImplTest.java @@ -0,0 +1,67 @@ +package com.fdc.appd.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito.*; +import org.mockito.MockitoAnnotations; + +import com.fdc.appd.datasources.JsonDatasourceConfig; +import com.fdc.appd.model.Application; + +public class V2ApplicationJsonReaderImplTest { + + @Mock + JsonDatasourceConfig jsonDatasourceConfig; + + @InjectMocks + private V2ApplicationJsonReaderImpl applicationJsonReaderImpl; + + @BeforeEach + public void setup() { + MockitoAnnotations.openMocks(this); // Initialize mocks + when(jsonDatasourceConfig.getPath()).thenReturn("test.local.v2.json"); + } + @Test + void testGetAllApplication() { + try { + assertEquals(4, applicationJsonReaderImpl.getAllApplication().getApplications().size()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + + + @Test + void testGetApplication() { + try { + Application app = applicationJsonReaderImpl.getApplication("ChannelsAppId"); + assertEquals("ChannelsApp", app.getName()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + @Test + void testGetApplicationFail() { + RuntimeException exception= assertThrows(RuntimeException.class, ()->{ + Application app = applicationJsonReaderImpl.getApplication("randomApp"); + assertEquals("ChannelsApp", app.getName()); + }); + assertEquals("Application Not found with the given appId", exception.getMessage()); + + + } +} diff --git a/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/resources/test.local.v2.json b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/resources/test.local.v2.json new file mode 100755 index 00000000..432ebd09 --- /dev/null +++ b/fdc3-appd-reference-Impl-java/fdc3-app-directory-java/src/test/resources/test.local.v2.json @@ -0,0 +1,220 @@ +{ + "applications": [ + { + "appId": "ChannelsAppId", + "name": "ChannelsApp", + "title": "Channels App", + "description": "Part of the FDC3 1.2 Conformance Tests", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/channels/" + }, + "hostManifests": { + "sail": { + "injectApi": "1.2", + "searchable": false + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/mock/Channels/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": false, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework Channels App" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework Intent App B" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ] + }, + { + "appId": "Conformance1", + "name": "Conformance1", + "title": "FDC3 1.2 Conformance Framework", + "description": "Testing Conformance", + "type": "web", + "details": { + "url": "https://finos.github.io/FDC3-conformance-framework/app/" + }, + "screenshots": [ + { + "src": "https://directory.fdc3.finos.org/assets/app/Conformance1.png" + } + ], + "hostManifests": { + "sail": { + "injectApi": "1.2" + }, + "finsemble": { + "window": { + "url": "https://finos.github.io/FDC3-conformance-framework/app/", + "affinity": "workspaceComponents", + "options": { + "resizable": true, + "autoShow": true, + "alwaysOnTop": false, + "addToWorkspace": true + }, + "top": "center", + "left": "center", + "width": 800, + "height": 600 + }, + "component": { + "displayName": "FDC3 Conformance Framework" + }, + "foreign": { + "services": { + "windowService": { + "allowSnapping": true, + "allowGrouping": true, + "allowTabbing": true, + "allowAutoArrange": true, + "allowMinimize": true + } + }, + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "alwaysOnTopIcon": false, + "FSBLHeader": { + "hideMaximize": false + }, + "persistWindowState": true, + "title": "FDC3 Conformance Framework" + } + } + } + } + }, + "version": "1.0.0", + "publisher": "Scott Logic", + "icons": [ + { + "src": "https://www.scottlogic.com/sites/default/files/scott-logic-favicon.jpg" + } + ] + }, + { + "appId": "tradingviewBlotter", + "name": "tradingviewBlotter", + "title": "TradingView Blotter", + "description": "A demo app for FDC3 using widgets from TradingView.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewBlotter/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tradingviewBlotter/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tradingviewBlotter.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewQuote": { + "displayName": "View Quote", + "contexts": [ + "fdc3.instrument" + ] + } + }, + "ViewInstrument": { + "displayName": "View Instrument", + "contexts": [ + "fdc3.instrument" + ] + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + }, + { + "appId": "tickerPrevClose", + "name": "tickerPrevClose", + "title": "Ticker Previous Close", + "description": "A snapshot of the pricing data for the ticker - going by previous market close, using data from Polygon.", + "icons": [ + { + "src": "https://apps.connectifi-interop.com/tickerPrevClose/icon.png" + } + ], + "screenshots": [ + { + "src": "https://apps.connectifi-interop.com/tickerPrevClose/screenshot.png" + } + ], + "type": "web", + "details": { + "url": "https://apps.connectifi-interop.com/sail/tickerPrevClose.html" + }, + "interop": { + "intents": { + "listensFor": { + "ViewQuote": { + "displayName": "View Quote", + "contexts": [ + "fdc3.instrument" + ] + } + } + } + }, + "hostManifests": { + "sail": { + "injectApi": "2.0" + } + } + } + ] +}