From 0eafdf775cf02b6d6d9de88af787b3e347bd6e98 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Mon, 13 Feb 2023 23:18:28 +0100 Subject: [PATCH 1/8] Authorize meta config update mutation by token. --- lib/type | 2 +- .../context/BCOGraphQLWebsocketContext.java | 9 ++- .../bco/api/graphql/context/GQLHeader.kt | 6 ++ .../graphql/schema/RegistrySchemaModule.java | 79 +++++++++++-------- .../unit/core/UnitRegistryController.java | 5 +- 5 files changed, 64 insertions(+), 37 deletions(-) create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLHeader.kt diff --git a/lib/type b/lib/type index 9f2ef6ac30..99e866c784 160000 --- a/lib/type +++ b/lib/type @@ -1 +1 @@ -Subproject commit 9f2ef6ac300fa26bd2c353dea96fdd6c3696fc48 +Subproject commit 99e866c78450e7ae410f2bc594a239b5b53ab970 diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java index c7b7a3a6ba..ccc21d93a6 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java @@ -32,6 +32,7 @@ public class BCOGraphQLWebsocketContext extends AbstractBCOGraphQLContext implements GraphQLWebSocketContext { + private final Session session; private final HandshakeRequest handshakeRequest; @@ -43,14 +44,14 @@ public BCOGraphQLWebsocketContext(DataLoaderRegistry dataLoaderRegistry, Session this.session = session; this.handshakeRequest = handshakeRequest; - if (handshakeRequest.getHeaders().get("Authorization") != null) { - this.token = handshakeRequest.getHeaders().get("Authorization").get(0); + if (handshakeRequest.getHeaders().get(GQLHeader.AUTHORIZATION.getKey()) != null) { + this.token = handshakeRequest.getHeaders().get(GQLHeader.AUTHORIZATION.getKey()).get(0); } else { this.token = null; } - if (handshakeRequest.getHeaders().get("Accept-Language") != null) { - final String language = handshakeRequest.getHeaders().get("Accept-Language").get(0); + if (handshakeRequest.getHeaders().get(GQLHeader.ACCEPT_LANGUAGE.getKey()) != null) { + final String language = handshakeRequest.getHeaders().get(GQLHeader.ACCEPT_LANGUAGE.getKey()).get(0); this.languageCode = (language != null) ? language : Locale.getDefault().getLanguage(); } else { this.languageCode = Locale.getDefault().getLanguage(); diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLHeader.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLHeader.kt new file mode 100644 index 0000000000..f17ba192da --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLHeader.kt @@ -0,0 +1,6 @@ +package org.openbase.bco.api.graphql.context + +enum class GQLHeader(var key: String) { + AUTHORIZATION("Authorization"), + ACCEPT_LANGUAGE("Accept-Language") +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java index 156aa131e4..08dd05edaf 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java @@ -34,18 +34,18 @@ import org.openbase.bco.api.graphql.error.GenericError; import org.openbase.bco.api.graphql.error.ServerError; import org.openbase.bco.authentication.lib.SessionManager; +import org.openbase.bco.authentication.lib.future.AuthenticatedValueFuture; import org.openbase.bco.authentication.lib.iface.BCOSession; import org.openbase.bco.registry.remote.Registries; import org.openbase.bco.registry.remote.session.BCOSessionImpl; -import org.openbase.bco.registry.unit.lib.filter.UnitConfigFilterImpl; import org.openbase.bco.registry.unit.remote.UnitRegistryRemote; import org.openbase.jul.exception.CouldNotPerformException; import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor; import org.openbase.jul.extension.type.processing.LabelProcessor; -import org.openbase.jul.pattern.Filter; -import org.openbase.jul.pattern.ListFilter; import org.openbase.type.configuration.EntryType; import org.openbase.type.configuration.MetaConfigType; +import org.openbase.type.domotic.authentication.AuthTokenType.AuthToken; +import org.openbase.type.domotic.authentication.AuthenticatedValueType.AuthenticatedValue; import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter; import org.openbase.type.domotic.unit.gateway.GatewayClassType.GatewayClass; @@ -54,19 +54,33 @@ import org.openbase.type.spatial.PlacementConfigType; import org.openbase.type.spatial.ShapeType; -import java.util.ArrayList; import java.util.Base64; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; public class RegistrySchemaModule extends SchemaModule { // ===================================== Queries =================================================================== + public static ImmutableList getUnitConfigs(final UnitFilter unitFilter, Boolean includeDisabledUnits) throws BCOGraphQLError { + try { + if ((includeDisabledUnits == null)) { + includeDisabledUnits = false; + } + return ImmutableList.copyOf( + Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigs(includeDisabledUnits, unitFilter)); + + } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { + throw new GenericError(ex); + } + } + /** * Check if an authentication token retrieved by the login method is still valid. * * @param token the token to be checked + * * @return if the token is valid and can be used to authenticate further requests */ @Query("verifyToken") @@ -80,9 +94,11 @@ Boolean verifyToken(@Arg("token") String token) { * * @param username the name of the user as plain text string. * @param passwordHash the password hash of the user that need to be generted first (see note below). + * * @return the login token. *

* Note: The hash of the default admin password is: '''R+gZ+PFuauhav8rRVa3XlWXXSEyi5BcdrbeXLEY3tDQ=''' + * * @throws BCOGraphQLError */ @Query("login") @@ -111,7 +127,8 @@ Boolean changePassword(@Arg("username") String username, @Arg("oldPassword") Str sessionManager.changePassword(userId, oldPassword, newPassword).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); return true; - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -130,13 +147,13 @@ ImmutableList queryGetUnitConfigs(@Arg("filter") UnitFilter unitFilt return getUnitConfigs(unitFilter, includeDisabledUnits); } + // ===================================== Mutations ================================================================= + @Query("gatewayClasses") ImmutableList gatewayClasses() throws CouldNotPerformException, InterruptedException { return ImmutableList.copyOf(Registries.getClassRegistry(true).getGatewayClasses()); } - // ===================================== Mutations ================================================================= - @Mutation("updateUnitConfig") UnitConfig updateUnitConfig(@Arg("unitConfig") UnitConfig unitConfig) throws BCOGraphQLError { try { @@ -145,7 +162,8 @@ UnitConfig updateUnitConfig(@Arg("unitConfig") UnitConfig unitConfig) throws BCO .toBuilder(); ProtoBufBuilderProcessor.mergeFromWithoutRepeatedFields(unitConfigBuilder, unitConfig); return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).updateUnitConfig(unitConfigBuilder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -155,7 +173,8 @@ UnitConfig removeUnitConfig(@Arg("unitId") String unitId) throws BCOGraphQLError try { final UnitConfig unitConfig = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId); return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).removeUnitConfig(unitConfig).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -164,7 +183,8 @@ UnitConfig removeUnitConfig(@Arg("unitId") String unitId) throws BCOGraphQLError UnitConfig registerUnitConfig(@Arg("unitConfig") UnitConfig unitConfig) throws BCOGraphQLError { try { return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).registerUnitConfig(unitConfig).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -179,7 +199,8 @@ LabelType.Label updateLabel(@Arg("unitId") String unitId, @Arg("label") String l LabelProcessor.replace(builder.getLabelBuilder(), oldLabel, label); return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getLabel(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -190,7 +211,8 @@ PlacementConfigType.PlacementConfig updateLocation(@Arg("unitId") String unitId, final UnitConfig.Builder builder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId).toBuilder(); builder.getPlacementConfigBuilder().setLocationId(locationId); return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -201,7 +223,8 @@ ShapeType.Shape updateFloorPlan(@Arg("locationId") String locationId, @Arg("shap final UnitConfig.Builder unitConfigBuilder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(locationId).toBuilder(); unitConfigBuilder.getPlacementConfigBuilder().getShapeBuilder().clearFloor().addAllFloor(shape.getFloorList()); return Registries.getUnitRegistry().updateUnitConfig(unitConfigBuilder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig().getShape(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } @@ -212,13 +235,16 @@ PoseType.Pose updatePose(@Arg("unitId") String unitId, @Arg("pose") PoseType.Pos final UnitConfig.Builder builder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId).toBuilder(); builder.getPlacementConfigBuilder().clearPose().setPose(pose); return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig().getPose(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | + TimeoutException ex) { throw new GenericError(ex); } } + // ===================================== Service Methods =========================================================== + @Mutation("updateMetaConfig") - MetaConfigType.MetaConfig updateMetaConfig(@Arg("unitId") String unitId, @Arg("entry") EntryType.Entry entry) throws BCOGraphQLError { + MetaConfigType.MetaConfig updateMetaConfig(@Arg("unitId") String unitId, @Arg("entry") EntryType.Entry entry, DataFetchingEnvironment env) throws BCOGraphQLError { try { final UnitRegistryRemote unitRegistry = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); @@ -233,23 +259,14 @@ MetaConfigType.MetaConfig updateMetaConfig(@Arg("unitId") String unitId, @Arg("e if (!entry.getValue().isEmpty()) { metaConfigBuilder.addEntry(entry); } - return unitRegistry.updateUnitConfig(unitConfigBuilder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getMetaConfig(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | TimeoutException ex) { - throw new GenericError(ex); - } - } - - // ===================================== Service Methods =========================================================== - - public static ImmutableList getUnitConfigs(final UnitFilter unitFilter, Boolean includeDisabledUnits) throws BCOGraphQLError { - try { - if ((includeDisabledUnits == null)) { - includeDisabledUnits = false; - } - return ImmutableList.copyOf( - Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigs(includeDisabledUnits, unitFilter)); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { + final SessionManager sessionManager = SessionManager.getInstance(); + final AuthToken authToken = AuthToken.newBuilder().setAuthenticationToken(((AbstractBCOGraphQLContext) env.getContext()).getToken()).build(); + final AuthenticatedValue request = sessionManager.initializeRequest(unitConfigBuilder.build(), authToken); + final Future future = unitRegistry.updateUnitConfigAuthenticated(request); + final AuthenticatedValueFuture authFuture = new AuthenticatedValueFuture(future, UnitConfig.class, request.getTicketAuthenticatorWrapper(), sessionManager); + return authFuture.get().getMetaConfig(); + } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException ex) { throw new GenericError(ex); } } diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java index 21ade6629d..142d2f8266 100644 --- a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java +++ b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java @@ -46,7 +46,10 @@ import org.openbase.bco.registry.unit.core.consistency.sceneconfig.SceneServiceStateConsistencyHandler; import org.openbase.bco.registry.unit.core.consistency.sceneconfig.ServiceStateDescriptionHierarchyConsistencyHandler; import org.openbase.bco.registry.unit.core.consistency.unitgroupconfig.*; -import org.openbase.bco.registry.unit.core.consistency.userconfig.*; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserConfigLanguageConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserConfigUserNameConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserPermissionConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserUnitLabelConsistencyHandler; import org.openbase.bco.registry.unit.core.plugin.*; import org.openbase.bco.registry.unit.lib.UnitRegistry; import org.openbase.bco.registry.unit.lib.auth.AuthorizationWithTokenHelper; From e765e984c10ddda4e829ff4342f2081383c947f8 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Thu, 16 Feb 2023 21:14:41 +0100 Subject: [PATCH 2/8] convert gql server to kotlin --- .../api/graphql/BcoApiGraphQlLauncher.java | 54 --- .../bco/api/graphql/BcoApiGraphQlLauncher.kt | 51 +++ .../BcoApiGraphQlSpringLaunchable.java | 106 ----- .../graphql/BcoApiGraphQlSpringLaunchable.kt | 91 ++++ ... => BcoGraphQlApiSpringBootApplication.kt} | 319 +++++++------ .../batchloader/BCOUnitBatchLoader.java | 65 --- .../graphql/batchloader/BCOUnitBatchLoader.kt | 47 ++ ...text.java => AbstractBCOGraphQLContext.kt} | 29 +- .../context/BCOGraphQLWebsocketContext.java | 82 ---- .../context/BCOGraphQLWebsocketContext.kt | 41 ++ .../context/DefaultBCOGraphQLContext.java | 55 --- .../context/DefaultBCOGraphQLContext.kt | 36 ++ .../graphql/discovery/ServiceAdvertiser.java | 172 ------- .../graphql/discovery/ServiceAdvertiser.kt | 179 ++++++++ .../discovery/ServiceDiscoveryDemo.java | 84 ---- .../graphql/discovery/ServiceDiscoveryDemo.kt | 83 ++++ .../{ErrorType.java => ArgumentError.kt} | 14 +- ...gumentError.java => AuthorizationError.kt} | 22 +- .../api/graphql/error/BCOGraphQLError.java | 16 +- .../{AuthorizationError.java => ErrorType.kt} | 20 +- .../bco/api/graphql/error/GenericError.java | 77 ---- .../bco/api/graphql/error/GenericError.kt | 62 +++ .../bco/api/graphql/error/ServerError.java | 51 --- .../bco/api/graphql/error/ServerError.kt | 40 ++ .../handler/CustomGraphQlErrorHandler.java | 75 --- .../handler/CustomGraphQlErrorHandler.kt | 57 +++ .../graphql/schema/RegistrySchemaModule.java | 273 ----------- .../graphql/schema/RegistrySchemaModule.kt | 427 ++++++++++++++++++ ...ionsAdd.java => SchemaModificationsAdd.kt} | 0 .../api/graphql/schema/UnitSchemaModule.java | 154 ------- .../api/graphql/schema/UnitSchemaModule.kt | 214 +++++++++ .../subscriptions/AbstractObserverMapper.java | 71 --- .../subscriptions/AbstractObserverMapper.kt | 71 +++ .../subscriptions/SubscriptionModule.java | 138 ------ .../subscriptions/SubscriptionModule.kt | 168 +++++++ ...tGroupMemberRecursionConsistencyHandler.kt | 19 +- 36 files changed, 1763 insertions(+), 1700 deletions(-) delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.kt rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/{BcoGraphQlApiSpringBootApplication.java => BcoGraphQlApiSpringBootApplication.kt} (60%) delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.kt rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/{AbstractBCOGraphQLContext.java => AbstractBCOGraphQLContext.kt} (61%) delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.kt rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/{ErrorType.java => ArgumentError.kt} (76%) rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/{ArgumentError.java => AuthorizationError.kt} (68%) rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/{AuthorizationError.java => ErrorType.kt} (67%) delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/{SchemaModificationsAdd.java => SchemaModificationsAdd.kt} (100%) delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.kt delete mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.java create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.kt diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.java deleted file mode 100644 index 5dccba3edb..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.openbase.bco.api.graphql; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import org.openbase.bco.authentication.lib.BCO; -import org.openbase.bco.authentication.lib.jp.JPCredentialsDirectory; -import org.openbase.jps.core.JPService; -import org.openbase.jps.preset.JPDebugMode; -import org.openbase.jul.communication.jp.JPComHost; -import org.openbase.jul.communication.jp.JPComPort; -import org.openbase.jul.pattern.launch.AbstractLauncher; - -public class BcoApiGraphQlLauncher extends AbstractLauncher { - - public BcoApiGraphQlLauncher() throws org.openbase.jul.exception.InstantiationException { - super(BcoApiGraphQlLauncher.class, BcoApiGraphQlSpringLaunchable.class); - } - - @Override - protected void loadProperties() { - JPService.registerProperty(JPDebugMode.class); - JPService.registerProperty(JPCredentialsDirectory.class); - JPService.registerProperty(JPComHost.class); - JPService.registerProperty(JPComPort.class); - } - - /** - * @param args the command line arguments - */ - public static void main(final String[] args) { - BCO.printLogo(); - AbstractLauncher.main(BCO.class, BcoApiGraphQlLauncher.class, args, BcoApiGraphQlLauncher.class); - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.kt new file mode 100644 index 0000000000..8e241f4d24 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlLauncher.kt @@ -0,0 +1,51 @@ +package org.openbase.bco.api.graphql + +import org.openbase.bco.authentication.lib.BCO +import org.openbase.bco.authentication.lib.jp.JPCredentialsDirectory +import org.openbase.jps.core.JPService +import org.openbase.jps.preset.JPDebugMode +import org.openbase.jul.communication.jp.JPComHost +import org.openbase.jul.communication.jp.JPComPort +import org.openbase.jul.pattern.launch.AbstractLauncher + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class BcoApiGraphQlLauncher : AbstractLauncher( + BcoApiGraphQlLauncher::class.java, BcoApiGraphQlSpringLaunchable::class.java +) { + override fun loadProperties() { + JPService.registerProperty(JPDebugMode::class.java) + JPService.registerProperty(JPCredentialsDirectory::class.java) + JPService.registerProperty(JPComHost::class.java) + JPService.registerProperty(JPComPort::class.java) + } + + companion object { + /** + * @param args the command line arguments + */ + @JvmStatic + fun main(args: Array) { + BCO.printLogo() + main(BCO::class.java, BcoApiGraphQlLauncher::class.java, args, BcoApiGraphQlLauncher::class.java) + } + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.java deleted file mode 100644 index b24cd074f6..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.openbase.bco.api.graphql; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import org.openbase.bco.api.graphql.discovery.ServiceAdvertiser; -import org.openbase.bco.registry.remote.Registries; -import org.openbase.bco.registry.remote.login.BCOLogin; -import org.openbase.jps.core.JPService; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.exception.InitializationException; -import org.openbase.jul.exception.InstantiationException; -import org.openbase.jul.iface.Launchable; -import org.openbase.jul.iface.VoidInitializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; - -import javax.jmdns.ServiceInfo.Fields; -import java.util.HashMap; -import java.util.UUID; - -public class BcoApiGraphQlSpringLaunchable implements Launchable, VoidInitializable { - - private static Logger LOGGER = LoggerFactory.getLogger(BcoApiGraphQlSpringLaunchable.class); - private ServiceAdvertiser serviceAdvertiser; - - - private ConfigurableApplicationContext context; - - @Override - public void init() throws InitializationException { - try { - serviceAdvertiser = ServiceAdvertiser.getInstance(); - } catch (InstantiationException ex) { - throw new InitializationException(this, ex); - } - } - - @Override - public void activate() throws CouldNotPerformException, InterruptedException { - LOGGER.info("Connect to bco..."); - Registries.waitUntilReady(); - - LOGGER.info("Login to bco..."); - BCOLogin.getSession().loginBCOUser(); - - LOGGER.info("Start webserver..."); - context = SpringApplication.run(BcoGraphQlApiSpringBootApplication.class, JPService.getArgs()); - - LOGGER.info("Advertise graphql service..."); - final HashMap qualifiedNameMap = new HashMap<>(); - qualifiedNameMap.put(Fields.Application, "http"); - qualifiedNameMap.put(Fields.Instance, "graphql-bco-openbase"); - qualifiedNameMap.put(Fields.Subtype, "graphql"); - - final HashMap propertyMap = new HashMap<>(); - propertyMap.put("bco-uuid", UUID.randomUUID().toString()); - propertyMap.put("path", "graphql"); - - // lookup port - final int port = Integer.parseInt(context.getEnvironment().getProperty("server.port")); - - // register service advertising - serviceAdvertiser.register(qualifiedNameMap, port, 0, 0, false, propertyMap); - } - - @Override - public void deactivate() { - - LOGGER.info("Logout..."); - serviceAdvertiser.shutdown(); - BCOLogin.getSession().logout(); - - if (isActive()) { - LOGGER.info("Shutdown " + context.getApplicationName()); - SpringApplication.exit(context); - context = null; - } - } - - @Override - public boolean isActive() { - return context != null && context.isActive(); - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.kt new file mode 100644 index 0000000000..7873332a77 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoApiGraphQlSpringLaunchable.kt @@ -0,0 +1,91 @@ +package org.openbase.bco.api.graphql + +import org.openbase.bco.api.graphql.discovery.ServiceAdvertiser +import org.openbase.bco.registry.remote.Registries +import org.openbase.bco.registry.remote.login.BCOLogin +import org.openbase.jps.core.JPService +import org.openbase.jul.exception.* +import org.openbase.jul.iface.Launchable +import org.openbase.jul.iface.VoidInitializable +import org.slf4j.LoggerFactory +import org.springframework.boot.SpringApplication +import org.springframework.context.ConfigurableApplicationContext +import java.util.* +import javax.jmdns.ServiceInfo + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class BcoApiGraphQlSpringLaunchable : Launchable, VoidInitializable { + private var serviceAdvertiser: ServiceAdvertiser? = null + private var context: ConfigurableApplicationContext? = null + + @Throws(InitializationException::class) + override fun init() { + serviceAdvertiser = try { + ServiceAdvertiser.instance + } catch (ex: InstantiationException) { + throw InitializationException(this, ex) + } + } + + @Throws(CouldNotPerformException::class, InterruptedException::class) + override fun activate() { + LOGGER.info("Connect to bco...") + Registries.waitUntilReady() + LOGGER.info("Login to bco...") + BCOLogin.getSession().loginBCOUser() + LOGGER.info("Start webserver...") + context = SpringApplication.run(BcoGraphQlApiSpringBootApplication::class.java, *JPService.getArgs()) + LOGGER.info("Advertise graphql service...") + val qualifiedNameMap = HashMap() + qualifiedNameMap[ServiceInfo.Fields.Application] = "http" + qualifiedNameMap[ServiceInfo.Fields.Instance] = "graphql-bco-openbase" + qualifiedNameMap[ServiceInfo.Fields.Subtype] = "graphql" + val propertyMap = HashMap() + propertyMap["bco-uuid"] = UUID.randomUUID().toString() + propertyMap["path"] = "graphql" + + // lookup port + context?.getEnvironment()?.getProperty("server.port")?.toInt()?.let { port -> + // register service advertising + serviceAdvertiser!!.register(qualifiedNameMap, port, 0, 0, false, propertyMap) + } + } + + override fun deactivate() { + LOGGER.info("Logout...") + serviceAdvertiser!!.shutdown() + BCOLogin.getSession().logout() + if (isActive) { + LOGGER.info("Shutdown " + context!!.applicationName) + SpringApplication.exit(context) + context = null + } + } + + override fun isActive(): Boolean { + return context != null && context!!.isActive + } + + companion object { + private val LOGGER = LoggerFactory.getLogger(BcoApiGraphQlSpringLaunchable::class.java) + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.kt similarity index 60% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.kt index 558fb6fd16..d5ceec9ddc 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/BcoGraphQlApiSpringBootApplication.kt @@ -1,4 +1,40 @@ -package org.openbase.bco.api.graphql; +package org.openbase.bco.api.graphql + +import com.google.api.graphql.execution.GuavaListenableFutureSupport +import com.google.api.graphql.rejoiner.* +import com.google.inject.Guice +import com.google.inject.Injector +import com.google.inject.Key +import com.google.inject.Provides +import graphql.Scalars +import graphql.execution.instrumentation.Instrumentation +import graphql.kickstart.execution.context.DefaultGraphQLContext +import graphql.kickstart.execution.context.GraphQLKickstartContext +import graphql.kickstart.servlet.context.GraphQLServletContextBuilder +import graphql.schema.* +import org.dataloader.DataLoader +import org.dataloader.DataLoaderRegistry +import org.openbase.bco.api.graphql.batchloader.BCOUnitBatchLoader +import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext +import org.openbase.bco.api.graphql.context.BCOGraphQLWebsocketContext +import org.openbase.bco.api.graphql.context.DefaultBCOGraphQLContext +import org.openbase.bco.api.graphql.schema.RegistrySchemaModule +import org.openbase.bco.api.graphql.schema.SchemaModificationsAdd +import org.openbase.bco.api.graphql.schema.SchemaModificationsRemove +import org.openbase.bco.api.graphql.schema.UnitSchemaModule +import org.openbase.bco.api.graphql.subscriptions.SubscriptionModule +import org.openbase.bco.registry.remote.Registries +import org.openbase.bco.registry.unit.lib.UnitRegistry +import org.openbase.jul.exception.NotAvailableException +import org.openbase.type.domotic.unit.UnitFilterType +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.context.annotation.Bean +import javax.servlet.http.HttpServletRequest +import javax.servlet.http.HttpServletResponse +import javax.websocket.Session +import javax.websocket.server.HandshakeRequest /*- * #%L @@ -20,122 +56,76 @@ * License along with this program. If not, see * . * #L% - */ + */@SpringBootApplication +open class BcoGraphQlApiSpringBootApplication { + private var injector: Injector? = null -import com.google.api.graphql.execution.GuavaListenableFutureSupport; -import com.google.api.graphql.rejoiner.GqlInputConverter; -import com.google.api.graphql.rejoiner.Schema; -import com.google.api.graphql.rejoiner.SchemaProviderModule; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Provides; -import graphql.Scalars; -import graphql.execution.instrumentation.Instrumentation; -import graphql.kickstart.execution.context.DefaultGraphQLContext; -import graphql.kickstart.execution.context.GraphQLKickstartContext; -import graphql.kickstart.servlet.context.GraphQLServletContextBuilder; -import graphql.schema.*; -import org.dataloader.DataLoader; -import org.dataloader.DataLoaderRegistry; -import org.openbase.bco.api.graphql.batchloader.BCOUnitBatchLoader; -import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext; -import org.openbase.bco.api.graphql.context.BCOGraphQLWebsocketContext; -import org.openbase.bco.api.graphql.context.DefaultBCOGraphQLContext; -import org.openbase.bco.api.graphql.schema.RegistrySchemaModule; -import org.openbase.bco.api.graphql.schema.SchemaModificationsAdd; -import org.openbase.bco.api.graphql.schema.SchemaModificationsRemove; -import org.openbase.bco.api.graphql.schema.UnitSchemaModule; -import org.openbase.bco.api.graphql.subscriptions.SubscriptionModule; -import org.openbase.bco.registry.remote.Registries; -import org.openbase.bco.registry.unit.lib.UnitRegistry; -import org.openbase.jul.exception.NotAvailableException; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.unit.UnitDataType.UnitData; -import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter; -import org.reactivestreams.Publisher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; + @Value("\${graphql.url:/graphql}") + private val graphqlurl: String? = null -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.Session; -import javax.websocket.server.HandshakeRequest; -import java.util.List; - -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; - -@SpringBootApplication -public class BcoGraphQlApiSpringBootApplication { - - private static Logger LOGGER = LoggerFactory.getLogger(BcoGraphQlApiSpringBootApplication.class); - - private final Injector injector; - @Value("${graphql.url:/graphql}") - private String graphqlurl; - - { + init { injector = Guice.createInjector( - new SchemaProviderModule(), - - // WARNING: - // The order of those two is important, see either class descriptions for details - new SchemaModificationsRemove(), - new SchemaModificationsAdd(), - - new RegistrySchemaModule(), - new UnitSchemaModule() - ); + SchemaProviderModule(), // WARNING: + // The order of those two is important, see either class descriptions for details + SchemaModificationsRemove(), + SchemaModificationsAdd(), + RegistrySchemaModule(), + UnitSchemaModule() + ) } @Bean - GraphQLSchema schema() { - GraphQLSchema schema = injector.getInstance(Key.get(GraphQLSchema.class, Schema.class)); - - final GraphQLOutputType unitDataOutputType = (GraphQLOutputType) schema.getType("openbase_type_domotic_unit_UnitData"); - final GraphQLOutputType unitConfigOutputType = (GraphQLOutputType) schema.getType("openbase_type_domotic_unit_UnitConfig"); - final GraphQLInputType unitFilterInputType = (GraphQLInputType) schema.getType("Input_openbase_type_domotic_unit_UnitFilter"); - final GqlInputConverter unitFilterInputConverter = GqlInputConverter.newBuilder().add(UnitFilter.getDescriptor().getFile()).build(); - - GraphQLObjectType.Builder builder = GraphQLObjectType.newObject().name("Subscription"); - builder.field(newFieldDefinition().name("units").type(unitDataOutputType) + open fun schema(): GraphQLSchema { + var schema = injector!!.getInstance( + Key.get( + GraphQLSchema::class.java, Schema::class.java + ) + ) + val unitDataOutputType = schema.getType("openbase_type_domotic_unit_UnitData") as GraphQLOutputType? + val unitConfigOutputType = schema.getType("openbase_type_domotic_unit_UnitConfig") as GraphQLOutputType? + val unitFilterInputType = schema.getType("Input_openbase_type_domotic_unit_UnitFilter") as GraphQLInputType? + val unitFilterInputConverter = + GqlInputConverter.newBuilder().add(UnitFilterType.UnitFilter.getDescriptor().file).build() + val builder = GraphQLObjectType.newObject().name("Subscription") + builder.field( + GraphQLFieldDefinition.newFieldDefinition().name("units").type(unitDataOutputType) .argument(GraphQLArgument.newArgument().name("filter").type(unitFilterInputType).build()) - .build()); - builder.field(newFieldDefinition().name("unitConfigs").type(GraphQLList.list(unitConfigOutputType)) + .build() + ) + builder.field( + GraphQLFieldDefinition.newFieldDefinition().name("unitConfigs").type(GraphQLList.list(unitConfigOutputType)) .argument(GraphQLArgument.newArgument().name("filter").type(unitFilterInputType)) .argument(GraphQLArgument.newArgument().name("includeDisabledUnits").type(Scalars.GraphQLBoolean)) - .build()); - - GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry(schema.getCodeRegistry()) - .dataFetcher(FieldCoordinates.coordinates("Subscription", "units"), new DataFetcher>() { - @Override - public Publisher get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception { - UnitFilter unitFilter = (UnitFilter) unitFilterInputConverter.createProtoBuf(UnitFilter.getDescriptor(), UnitFilter.newBuilder(), dataFetchingEnvironment.getArgument("filter")); - return SubscriptionModule.subscribeUnits(unitFilter); - } - }) - .dataFetcher(FieldCoordinates.coordinates("Subscription", "unitConfigs"), new DataFetcher>>() { - @Override - public Publisher> get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception { - UnitFilter unitFilter = (UnitFilter) unitFilterInputConverter.createProtoBuf(UnitFilter.getDescriptor(), UnitFilter.newBuilder(), dataFetchingEnvironment.getArgument("filter")); - - Boolean includeDisabledUnits = false; - if (dataFetchingEnvironment.getArgument("includeDisabledUnits") != null) { - includeDisabledUnits = dataFetchingEnvironment.getArgument("includeDisabledUnits"); - } - - return SubscriptionModule.subscribeUnitConfigs(unitFilter, includeDisabledUnits); + .build() + ) + val codeRegistry = GraphQLCodeRegistry.newCodeRegistry(schema.codeRegistry) + .dataFetcher(FieldCoordinates.coordinates("Subscription", "units"), DataFetcher { dataFetchingEnvironment -> + val unitFilter = unitFilterInputConverter.createProtoBuf( + UnitFilterType.UnitFilter.getDescriptor(), + UnitFilterType.UnitFilter.newBuilder(), + dataFetchingEnvironment.getArgument("filter") + ) as UnitFilterType.UnitFilter + SubscriptionModule.subscribeUnits(unitFilter) + }) + .dataFetcher( + FieldCoordinates.coordinates("Subscription", "unitConfigs"), + DataFetcher { dataFetchingEnvironment -> + val unitFilter = unitFilterInputConverter.createProtoBuf( + UnitFilterType.UnitFilter.getDescriptor(), + UnitFilterType.UnitFilter.newBuilder(), + dataFetchingEnvironment.getArgument("filter") + ) as UnitFilterType.UnitFilter + var includeDisabledUnits = false + if (dataFetchingEnvironment.getArgument("includeDisabledUnits") != null) { + includeDisabledUnits = dataFetchingEnvironment.getArgument("includeDisabledUnits") } + SubscriptionModule.subscribeUnitConfigs(unitFilter, includeDisabledUnits) }) - .build(); - + .build() schema = GraphQLSchema.newSchema(schema) - .subscription(builder.build()) - .codeRegistry(codeRegistry) - .build(); + .subscription(builder.build()) + .codeRegistry(codeRegistry) + .build() //final GraphQLObjectType.Builder queryTypeBuilder = GraphQLObjectType.newObject(schema.getQueryType()); // final GraphQLObjectType.Builder mutationTypeBuilder = GraphQLObjectType.newObject(schema.getMutationType()); @@ -201,9 +191,7 @@ public Boolean get(DataFetchingEnvironment dataFetchingEnvironment) throws Excep .query(queryTypeBuilder.build()) .mutation(mutationTypeBuilder.build()) .codeRegistry(codeRegistry) - .build();*/ - - return schema; + .build();*/return schema } /*@Bean @@ -211,80 +199,74 @@ public GraphQL graphQL() { System.out.println("Add exec strategy.."); return GraphQL.newGraphQL(schema()).subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()).build(); }*/ -// -// @Bean -// public GraphQL graphQL() { -// return GraphQL.newGraphQL(schemaProvider().getSchema()).build(); -// } - + // + // @Bean + // public GraphQL graphQL() { + // return GraphQL.newGraphQL(schemaProvider().getSchema()).build(); + // } @Bean - public Instrumentation instrumentation() { - return GuavaListenableFutureSupport.listenableFutureInstrumentation(); + open fun instrumentation(): Instrumentation { + return GuavaListenableFutureSupport.listenableFutureInstrumentation() } @Bean - public UnitRegistry unitRegistry() { - try { - return Registries.getUnitRegistry(); - } catch (NotAvailableException e) { - e.printStackTrace(); - return null; + open fun unitRegistry(): UnitRegistry? { + return try { + Registries.getUnitRegistry() + } catch (e: NotAvailableException) { + e.printStackTrace() + null } } @Bean @Provides - public DataLoaderRegistry buildDataLoaderRegistry(BCOUnitBatchLoader bcoUnitBatchLoader) { - DataLoaderRegistry registry = new DataLoaderRegistry(); - registry.register(AbstractBCOGraphQLContext.DATA_LOADER_UNITS, new DataLoader<>(bcoUnitBatchLoader)); - return registry; + open fun buildDataLoaderRegistry(bcoUnitBatchLoader: BCOUnitBatchLoader): DataLoaderRegistry { + val registry = DataLoaderRegistry() + registry.register(AbstractBCOGraphQLContext.Companion.DATA_LOADER_UNITS, DataLoader(bcoUnitBatchLoader)) + return registry } @Bean - public GraphQLServletContextBuilder contextBuilder(DataLoaderRegistry dataLoaderRegistry) { - return new GraphQLServletContextBuilder() { - - @Override - public GraphQLKickstartContext build(HttpServletRequest request, HttpServletResponse response) { - return new DefaultBCOGraphQLContext(dataLoaderRegistry, request); + open fun contextBuilder(dataLoaderRegistry: DataLoaderRegistry): GraphQLServletContextBuilder { + return object : GraphQLServletContextBuilder { + override fun build(request: HttpServletRequest, response: HttpServletResponse): GraphQLKickstartContext { + return DefaultBCOGraphQLContext(dataLoaderRegistry, request) } - @Override - public GraphQLKickstartContext build() { - return new DefaultGraphQLContext(dataLoaderRegistry, null); + override fun build(): GraphQLKickstartContext { + return DefaultGraphQLContext(dataLoaderRegistry, null) } - @Override - public GraphQLKickstartContext build(Session session, HandshakeRequest request) { - return new BCOGraphQLWebsocketContext(dataLoaderRegistry, session, request); + override fun build(session: Session, request: HandshakeRequest): GraphQLKickstartContext { + return BCOGraphQLWebsocketContext( + session = session, + handshakeRequest = request, + dataLoaderRegistry = dataLoaderRegistry + ) } - }; - } - - -// @Autowired -// GraphQLDataFetchers graphQLDataFetchers; - -// public static void main(String[] args) throws InterruptedException, CouldNotPerformException { -// String schema = "type Query{hello: String}"; -// -// SchemaParser schemaParser = new SchemaParser(); -// TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema); -// -// RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() -// .type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world"))) -// .build(); -// -// SchemaGenerator schemaGenerator = new SchemaGenerator(); -// GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); -// -// GraphQL build = GraphQL.newGraphQL(new GraphQLProvider().buildSchema()).build(); -// ExecutionResult executionResult = build.execute("{bookById(id: \"book-1\"){name}}"); -// -// System.out.println(executionResult.getData().toString()); - -// } - + } + } // @Autowired + + // GraphQLDataFetchers graphQLDataFetchers; + // public static void main(String[] args) throws InterruptedException, CouldNotPerformException { + // String schema = "type Query{hello: String}"; + // + // SchemaParser schemaParser = new SchemaParser(); + // TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema); + // + // RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + // .type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world"))) + // .build(); + // + // SchemaGenerator schemaGenerator = new SchemaGenerator(); + // GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); + // + // GraphQL build = GraphQL.newGraphQL(new GraphQLProvider().buildSchema()).build(); + // ExecutionResult executionResult = build.execute("{bookById(id: \"book-1\"){name}}"); + // + // System.out.println(executionResult.getData().toString()); + // } /*private static final ImmutableList STATIC_FIELD = ImmutableList.of(newFieldDefinition().type(Scalars.GraphQLString).name("_").staticValue("-").build()); @@ -371,13 +353,16 @@ static GraphQLEnumType convert( return builder.build(); } - /** Returns the GraphQL name of the supplied proto. */ + / ** Returns the GraphQL name of the supplied proto. */ /*static String getReferenceName(Descriptors.GenericDescriptor descriptor) { return CharMatcher.anyOf(".").replaceFrom(descriptor.getFullName(), "_"); } - /** Returns a reference to the GraphQL type corresponding to the supplied proto. */ + / ** Returns a reference to the GraphQL type corresponding to the supplied proto. */ /*static GraphQLTypeReference getReference(Descriptors.GenericDescriptor descriptor) { return new GraphQLTypeReference(getReferenceName(descriptor)); }*/ + companion object { + private val LOGGER = LoggerFactory.getLogger(BcoGraphQlApiSpringBootApplication::class.java) + } } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.java deleted file mode 100644 index c063324e31..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.openbase.bco.api.graphql.batchloader; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import lombok.extern.slf4j.Slf4j; -import org.dataloader.BatchLoader; -import org.openbase.bco.registry.unit.lib.UnitRegistry; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.exception.printer.ExceptionPrinter; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -@Component -public class BCOUnitBatchLoader implements BatchLoader { - - private final org.slf4j.Logger log = LoggerFactory.getLogger(getClass()); - - private final UnitRegistry unitRegistry; - - public BCOUnitBatchLoader(UnitRegistry unitRegistry) { - this.unitRegistry = unitRegistry; - } - - @Override - public CompletionStage> load(List ids) { - - final List unitConfigList = new ArrayList<>(); - - for (String id : ids) { - try { - unitConfigList.add(unitRegistry.getUnitConfigById(id)); - } catch (CouldNotPerformException ex) { - ExceptionPrinter.printHistory("Could not resolve all unit config by id!", ex, log); - } - } - - return CompletableFuture.completedFuture(unitConfigList); - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.kt new file mode 100644 index 0000000000..1ddd83fe5a --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/batchloader/BCOUnitBatchLoader.kt @@ -0,0 +1,47 @@ +package org.openbase.bco.api.graphql.batchloader + +import org.dataloader.BatchLoader +import org.openbase.bco.registry.unit.lib.UnitRegistry +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.exception.printer.ExceptionPrinter +import org.openbase.type.domotic.unit.UnitConfigType +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */@Component +class BCOUnitBatchLoader(private val unitRegistry: UnitRegistry) : BatchLoader { + private val log = LoggerFactory.getLogger(javaClass) + override fun load(ids: List): CompletionStage> { + val unitConfigList: MutableList = ArrayList() + for (id in ids) { + try { + unitConfigList.add(unitRegistry.getUnitConfigById(id)) + } catch (ex: CouldNotPerformException) { + ExceptionPrinter.printHistory("Could not resolve all unit config by id!", ex, log) + } + } + return CompletableFuture.completedFuture(unitConfigList) + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt similarity index 61% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt index 916874a12c..ab942b6249 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt @@ -1,4 +1,8 @@ -package org.openbase.bco.api.graphql.context; +package org.openbase.bco.api.graphql.context + +import graphql.kickstart.execution.context.DefaultGraphQLContext +import org.dataloader.DataLoaderRegistry +import org.openbase.jul.exception.NotAvailableException /*- * #%L @@ -20,21 +24,14 @@ * License along with this program. If not, see * . * #L% - */ - -import graphql.kickstart.execution.context.DefaultGraphQLContext; -import org.dataloader.DataLoaderRegistry; -import org.openbase.jul.exception.NotAvailableException; - -public abstract class AbstractBCOGraphQLContext extends DefaultGraphQLContext { + */ abstract class AbstractBCOGraphQLContext( + dataLoaderRegistry: DataLoaderRegistry?, +) : DefaultGraphQLContext(dataLoaderRegistry) { + @get:Throws(NotAvailableException::class) + abstract val token: String? + abstract val languageCode: String? - public static final String DATA_LOADER_UNITS = "units"; - - public AbstractBCOGraphQLContext(DataLoaderRegistry dataLoaderRegistry) { - super(dataLoaderRegistry); + companion object { + const val DATA_LOADER_UNITS = "units" } - - public abstract String getToken() throws NotAvailableException; - - public abstract String getLanguageCode(); } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java deleted file mode 100644 index ccc21d93a6..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.openbase.bco.api.graphql.context; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import graphql.kickstart.servlet.context.GraphQLWebSocketContext; -import org.dataloader.DataLoaderRegistry; -import org.openbase.jul.exception.NotAvailableException; - -import javax.websocket.Session; -import javax.websocket.server.HandshakeRequest; -import java.util.Locale; - -public class BCOGraphQLWebsocketContext extends AbstractBCOGraphQLContext implements GraphQLWebSocketContext { - - - private final Session session; - private final HandshakeRequest handshakeRequest; - - private final String token; - private final String languageCode; - - public BCOGraphQLWebsocketContext(DataLoaderRegistry dataLoaderRegistry, Session session, HandshakeRequest handshakeRequest) { - super(dataLoaderRegistry); - this.session = session; - this.handshakeRequest = handshakeRequest; - - if (handshakeRequest.getHeaders().get(GQLHeader.AUTHORIZATION.getKey()) != null) { - this.token = handshakeRequest.getHeaders().get(GQLHeader.AUTHORIZATION.getKey()).get(0); - } else { - this.token = null; - } - - if (handshakeRequest.getHeaders().get(GQLHeader.ACCEPT_LANGUAGE.getKey()) != null) { - final String language = handshakeRequest.getHeaders().get(GQLHeader.ACCEPT_LANGUAGE.getKey()).get(0); - this.languageCode = (language != null) ? language : Locale.getDefault().getLanguage(); - } else { - this.languageCode = Locale.getDefault().getLanguage(); - } - } - - @Override - public Session getSession() { - return session; - } - - @Override - public HandshakeRequest getHandshakeRequest() { - return handshakeRequest; - } - - public String getToken() throws NotAvailableException { - if (token == null) { - throw new NotAvailableException("AuthToken"); - } - - return token; - } - - public String getLanguageCode() { - return this.languageCode; - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.kt new file mode 100644 index 0000000000..28519f4c65 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/BCOGraphQLWebsocketContext.kt @@ -0,0 +1,41 @@ +package org.openbase.bco.api.graphql.context + +import graphql.kickstart.execution.context.GraphQLKickstartContext +import org.dataloader.DataLoaderRegistry +import java.util.* +import javax.websocket.Session +import javax.websocket.server.HandshakeRequest + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +data class BCOGraphQLWebsocketContext( + val session: Session, + val handshakeRequest: HandshakeRequest, + private val dataLoaderRegistry: DataLoaderRegistry, +) : AbstractBCOGraphQLContext(dataLoaderRegistry), GraphQLKickstartContext { + override val token: String? + get() + = handshakeRequest.headers[GQLHeader.AUTHORIZATION.key]?.get(0) + override val languageCode: String? + get() + = handshakeRequest.headers[GQLHeader.ACCEPT_LANGUAGE.key]?.get(0) ?: Locale.getDefault().language +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.java deleted file mode 100644 index 0652e37a01..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.openbase.bco.api.graphql.context; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import org.dataloader.DataLoaderRegistry; -import org.openbase.jul.exception.NotAvailableException; - -import javax.servlet.http.HttpServletRequest; -import java.util.Locale; - -public class DefaultBCOGraphQLContext extends AbstractBCOGraphQLContext { - - private final String token; - private final String languageCode; - - public DefaultBCOGraphQLContext(DataLoaderRegistry dataLoaderRegistry, HttpServletRequest request) { - super(dataLoaderRegistry); - this.token = request.getHeader("Authorization"); - - final String language = request.getHeader("Accept-Language"); - this.languageCode = (language != null) ? language : Locale.getDefault().getLanguage(); - } - - public String getToken() throws NotAvailableException { - if (token == null) { - throw new NotAvailableException("AuthToken"); - } - - return token; - } - - public String getLanguageCode() { - return this.languageCode; - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.kt new file mode 100644 index 0000000000..8353c4cb83 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/DefaultBCOGraphQLContext.kt @@ -0,0 +1,36 @@ +package org.openbase.bco.api.graphql.context + +import org.dataloader.DataLoaderRegistry +import java.util.* +import javax.servlet.http.HttpServletRequest + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +class DefaultBCOGraphQLContext( + dataLoaderRegistry: DataLoaderRegistry, + private val request: HttpServletRequest, +) : AbstractBCOGraphQLContext(dataLoaderRegistry) { + override val token: String? + get() = request.getHeader("Authorization") + override val languageCode: String? + get() = request.getHeader("Accept-Language") ?: Locale.getDefault().language +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.java deleted file mode 100644 index 83abd735fa..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.java +++ /dev/null @@ -1,172 +0,0 @@ -package org.openbase.bco.api.graphql.discovery; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import org.openbase.jps.core.JPService; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.exception.InstantiationException; -import org.openbase.jul.exception.printer.ExceptionPrinter; -import org.openbase.jul.iface.Shutdownable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jmdns.JmDNS; -import javax.jmdns.ServiceInfo; -import javax.jmdns.ServiceInfo.Fields; -import java.io.IOException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.*; - -public class ServiceAdvertiser implements Shutdownable { - - private static Logger LOGGER = LoggerFactory.getLogger(ServiceAdvertiser.class); - - private static ServiceAdvertiser instance; - - private final List domainNameServices; - - private ServiceAdvertiser() throws InstantiationException { - this.domainNameServices = new ArrayList<>(); - - // skip advertising in debug mode - if (JPService.debugMode()) { - return; - } - - -// try { // disabled since its not used yet but causes some network service loops. service might be replaced by another implementation. -// domainNameServices.add(JmDNS.create()); -// } catch (IOException ex) { -// ExceptionPrinter.printHistory("Could not initiate domain name service for default interface!", ex, LOGGER); -// } - -// for (InetAddress localHostLANAddress : getLocalHostLANAddress()) { -// System.err.println("interface: "+localHostLANAddress.getHostAddress()); -// try { -// domainNameServices.add(JmDNS.create(localHostLANAddress)); -// } catch (IOException ex) { -// ExceptionPrinter.printHistory("Could not initiate domain name service for interface: " + localHostLANAddress.getAddress(), ex, LOGGER); -// } -// } - } - - /** - * Method tries to resolve the best local network interface address that can be used to advertise inet services. - */ - private static List getLocalHostLANAddress() { - - final List siteLocal = new ArrayList<>(); - final List local = new ArrayList<>(); - final List loopback = new ArrayList<>(); - - try { - // Iterate all NICs (network interface cards)... - for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) { - // Iterate all IP addresses assigned to each card... - for (Enumeration inetAddrs = ifaces.nextElement().getInetAddresses(); inetAddrs.hasMoreElements(); ) { - InetAddress inetAddr = (InetAddress) inetAddrs.nextElement(); - - // check if site local - if (inetAddr.isSiteLocalAddress()) { - siteLocal.add(inetAddr); - continue; - } - - // check if loopback - if (inetAddr.isLoopbackAddress()) { - loopback.add(inetAddr); - continue; - } - - // add other - local.add(inetAddr); - } - } - - // prefer site local addresses - if (!siteLocal.isEmpty()) { - System.out.println("found site local: " + siteLocal.size()); - return siteLocal; - } - - // prefer local if site local is not available - if (!local.isEmpty()) { - System.out.println("found local: " + local.size()); - return local; - } - - // fallback with loopback device - if (!loopback.isEmpty()) { - System.out.println("found loopback: " + loopback.size()); - return loopback; - } - } catch (final SocketException ex) { - // try default inet address as fallback - try { - local.add(InetAddress.getLocalHost()); - } catch (UnknownHostException e) { - // otherwise just return empty list. - } - } - return local; - } - - public static synchronized ServiceAdvertiser getInstance() throws InstantiationException { - if (instance == null) { - instance = new ServiceAdvertiser(); - } - return instance; - } - - public List register(final HashMap qualifiedNameMap, final int port, final int weight, final int priority, final boolean persistent, final Map props) throws CouldNotPerformException { - try { - final List serviceInfoList = new ArrayList<>(); - for (JmDNS domainNameService : domainNameServices) { - - // Register the service - final ServiceInfo serviceInfo = ServiceInfo.create(qualifiedNameMap, port, weight, priority, false, props); - domainNameService.registerService(serviceInfo); - serviceInfoList.add(serviceInfo); - } - return serviceInfoList; - } catch (IOException ex) { - throw new CouldNotPerformException("Could not register service!", ex); - } - } - - public void deregisterService(final ServiceInfo serviceInfo) { - for (JmDNS domainNameService : domainNameServices) { - domainNameService.unregisterService(serviceInfo); - } - } - - @Override - public void shutdown() { - for (JmDNS domainNameService : domainNameServices) { - domainNameService.unregisterAllServices(); - } - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.kt new file mode 100644 index 0000000000..cb4ec55219 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceAdvertiser.kt @@ -0,0 +1,179 @@ +package org.openbase.bco.api.graphql.discovery + +import org.openbase.jps.core.JPService +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.exception.InstantiationException +import org.openbase.jul.iface.Shutdownable +import org.slf4j.LoggerFactory +import java.io.IOException +import java.net.InetAddress +import java.net.NetworkInterface +import java.net.SocketException +import java.net.UnknownHostException +import java.util.* +import javax.jmdns.JmDNS +import javax.jmdns.ServiceInfo + + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class ServiceAdvertiser private constructor() : Shutdownable { + private val domainNameServices: List + + init { + domainNameServices = ArrayList() + + // skip advertising in debug mode + if (!JPService.debugMode()) { + // disabled since its not used yet but causes some network service loops. service might be replaced by another implementation. +// try { domainNameServices.add( +// JmDNS.create()) +// } catch (ex: IOException) { +// ExceptionPrinter.printHistory( +// "Could not initiate domain name service for default interface!", +// ex, +// LOGGER +// ) +// } +// +// for (localHostLANAddress in getLocalHostLANAddress()) { +// System.err.println("interface: " + localHostLANAddress.hostAddress) +// try { +// domainNameServices.add(JmDNS.create(localHostLANAddress)) +// } catch (ex: IOException) { +// ExceptionPrinter.printHistory( +// "Could not initiate domain name service for interface: " + localHostLANAddress.address, +// ex, +// LOGGER +// ) +// } +// } + } + } + + @Throws(CouldNotPerformException::class) + fun register( + qualifiedNameMap: HashMap?, + port: Int, + weight: Int, + priority: Int, + persistent: Boolean, + props: Map?, + ): List { + return try { + val serviceInfoList: MutableList = ArrayList() + for (domainNameService in domainNameServices) { + + // Register the service + val serviceInfo = ServiceInfo.create(qualifiedNameMap, port, weight, priority, false, props) + domainNameService.registerService(serviceInfo) + serviceInfoList.add(serviceInfo) + } + serviceInfoList + } catch (ex: IOException) { + throw CouldNotPerformException("Could not register service!", ex) + } + } + + fun deregisterService(serviceInfo: ServiceInfo?) { + for (domainNameService in domainNameServices) { + domainNameService.unregisterService(serviceInfo) + } + } + + override fun shutdown() { + for (domainNameService in domainNameServices) { + domainNameService.unregisterAllServices() + } + } + + companion object { + private val LOGGER = LoggerFactory.getLogger(ServiceAdvertiser::class.java) + + + @get:Throws(InstantiationException::class) + @get:Synchronized + val instance: ServiceAdvertiser by lazy { ServiceAdvertiser() } + + private val localHostLANAddress: List + /** + * Method tries to resolve the best local network interface address that can be used to advertise inet services. + */ + private get() { + val siteLocal: MutableList = ArrayList() + val local: MutableList = ArrayList() + val loopback: MutableList = ArrayList() + try { + // Iterate all NICs (network interface cards)... + val ifaces = NetworkInterface.getNetworkInterfaces() + while (ifaces.hasMoreElements()) { + + // Iterate all IP addresses assigned to each card... + val inetAddrs: Enumeration<*> = ifaces.nextElement().inetAddresses + while (inetAddrs.hasMoreElements()) { + val inetAddr = inetAddrs.nextElement() as InetAddress + + // check if site local + if (inetAddr.isSiteLocalAddress) { + siteLocal.add(inetAddr) + continue + } + + // check if loopback + if (inetAddr.isLoopbackAddress) { + loopback.add(inetAddr) + continue + } + + // add other + local.add(inetAddr) + } + } + + // prefer site local addresses + if (!siteLocal.isEmpty()) { + println("found site local: " + siteLocal.size) + return siteLocal + } + + // prefer local if site local is not available + if (!local.isEmpty()) { + println("found local: " + local.size) + return local + } + + // fallback with loopback device + if (!loopback.isEmpty()) { + println("found loopback: " + loopback.size) + return loopback + } + } catch (ex: SocketException) { + // try default inet address as fallback + try { + local.add(InetAddress.getLocalHost()) + } catch (e: UnknownHostException) { + // otherwise just return empty list. + } + } + return local + } + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.java deleted file mode 100644 index be1342b6c4..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.openbase.bco.api.graphql.discovery; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import org.openbase.jul.processing.StringProcessor; - -import javax.jmdns.JmDNS; -import javax.jmdns.ServiceEvent; -import javax.jmdns.ServiceListener; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -public class ServiceDiscoveryDemo { - - private static class SampleListener implements ServiceListener { - - private final String serviceNameFilter; - - public SampleListener(final String serviceNameFilter) { - this.serviceNameFilter = serviceNameFilter; - } - - public SampleListener() { - this.serviceNameFilter = null; - } - - @Override - public void serviceAdded(ServiceEvent event) { - } - - @Override - public void serviceRemoved(ServiceEvent event) { - if(serviceNameFilter == null || event.getName().equals(serviceNameFilter)) { - System.out.println("Offline: " + event.getName() + "@" + event.getInfo().getServer() + ":" + event.getInfo().getPort() + " - " + StringProcessor.transformCollectionToString(Arrays.asList(event.getInfo().getHostAddresses().clone()), ", ")); - } - } - - @Override - public void serviceResolved(ServiceEvent event) { - if(serviceNameFilter == null || event.getName().equals(serviceNameFilter)) { - System.out.println("Online: " + event.getName() + "@" + event.getInfo().getServer() + ":" + event.getInfo().getPort() + " - " + StringProcessor.transformCollectionToString(Arrays.asList(event.getInfo().getHostAddresses().clone()), ", ")); - } - } - } - - public static void disabledMain(String[] args) throws InterruptedException { - try { - // Create a JmDNS instance - JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost()); - - // Add a service listener - jmdns.addServiceListener("_http._tcp.local.", new SampleListener("graphql-bco-openbase")); - - // Wait a bit - Thread.sleep(30000); - } catch (UnknownHostException e) { - System.out.println(e.getMessage()); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.kt new file mode 100644 index 0000000000..0d10a4b94f --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/discovery/ServiceDiscoveryDemo.kt @@ -0,0 +1,83 @@ +package org.openbase.bco.api.graphql.discovery + +import org.openbase.jul.processing.StringProcessor +import java.io.IOException +import java.net.InetAddress +import java.net.UnknownHostException +import java.util.* +import javax.jmdns.JmDNS +import javax.jmdns.ServiceEvent +import javax.jmdns.ServiceListener + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ object ServiceDiscoveryDemo { + @Throws(InterruptedException::class) + fun disabledMain(args: Array?) { + try { + // Create a JmDNS instance + val jmdns = JmDNS.create(InetAddress.getLocalHost()) + + // Add a service listener + jmdns.addServiceListener("_http._tcp.local.", SampleListener("graphql-bco-openbase")) + + // Wait a bit + Thread.sleep(30000) + } catch (e: UnknownHostException) { + println(e.message) + } catch (e: IOException) { + println(e.message) + } + } + + private class SampleListener : ServiceListener { + private val serviceNameFilter: String? + + constructor(serviceNameFilter: String?) { + this.serviceNameFilter = serviceNameFilter + } + + constructor() { + serviceNameFilter = null + } + + override fun serviceAdded(event: ServiceEvent) {} + override fun serviceRemoved(event: ServiceEvent) { + if (serviceNameFilter == null || event.name == serviceNameFilter) { + println( + "Offline: " + event.name + "@" + event.info.server + ":" + event.info.port + " - " + StringProcessor.transformCollectionToString( + Arrays.asList(*event.info.hostAddresses.clone()), ", " + ) + ) + } + } + + override fun serviceResolved(event: ServiceEvent) { + if (serviceNameFilter == null || event.name == serviceNameFilter) { + println( + "Online: " + event.name + "@" + event.info.server + ":" + event.info.port + " - " + StringProcessor.transformCollectionToString( + Arrays.asList(*event.info.hostAddresses.clone()), ", " + ) + ) + } + } + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.kt similarity index 76% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.kt index e8daff92f5..b7a85d3f43 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.kt @@ -1,4 +1,4 @@ -package org.openbase.bco.api.graphql.error; +package org.openbase.bco.api.graphql.error /*- * #%L @@ -21,15 +21,7 @@ * . * #L% */ +class ArgumentError(cause: Throwable) : BCOGraphQLError(cause) { -import graphql.ErrorClassification; - -public enum ErrorType implements ErrorClassification { - - ARGUMENT_ERROR, - AUTHORIZATION_ERROR, - SERVER_ERROR; - - private ErrorType() { - } + override fun getErrorType() = ErrorType.ARGUMENT_ERROR } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.kt similarity index 68% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.kt index 2f3eed9eb0..8a60743e62 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ArgumentError.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.kt @@ -1,4 +1,6 @@ -package org.openbase.bco.api.graphql.error; +package org.openbase.bco.api.graphql.error + +import graphql.ErrorClassification /*- * #%L @@ -20,20 +22,8 @@ * License along with this program. If not, see * . * #L% - */ - -import graphql.ErrorClassification; - -public class ArgumentError extends BCOGraphQLError { - - public ArgumentError(final Throwable cause) { - super(cause.getMessage(), cause); + */ class AuthorizationError(cause: Throwable) : BCOGraphQLError(cause) { + override fun getErrorType(): ErrorClassification { + return ErrorType.AUTHORIZATION_ERROR } - - @Override - public ErrorClassification getErrorType() { - return ErrorType.ARGUMENT_ERROR; - } - - } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/BCOGraphQLError.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/BCOGraphQLError.java index c5d3fdb548..da3a5fc990 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/BCOGraphQLError.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/BCOGraphQLError.java @@ -10,12 +10,12 @@ * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public * License along with this program. If not, see * . @@ -32,8 +32,8 @@ public abstract class BCOGraphQLError extends Exception implements GraphQLError private List path = null; private List locations = null; - public BCOGraphQLError(final String message, final Throwable cause) { - super(message, cause); + public BCOGraphQLError(final Throwable cause) { + super(cause.getMessage(), cause); } @Override @@ -41,15 +41,15 @@ public List getLocations() { return locations; } + public void setLocations(final List locations) { + this.locations = locations; + } + @Override public List getPath() { return path; } - public void setLocations(final List locations) { - this.locations = locations; - } - public void setPath(final List path) { this.path = path; } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.kt similarity index 67% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.kt index 567d191b5f..f285ce43c8 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/AuthorizationError.java +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ErrorType.kt @@ -1,4 +1,6 @@ -package org.openbase.bco.api.graphql.error; +package org.openbase.bco.api.graphql.error + +import graphql.ErrorClassification /*- * #%L @@ -20,18 +22,6 @@ * License along with this program. If not, see * . * #L% - */ - -import graphql.ErrorClassification; - -public class AuthorizationError extends BCOGraphQLError { - - public AuthorizationError(String message, Throwable cause) { - super(message, cause); - } - - @Override - public ErrorClassification getErrorType() { - return ErrorType.AUTHORIZATION_ERROR; - } + */ enum class ErrorType : ErrorClassification { + ARGUMENT_ERROR, AUTHORIZATION_ERROR, SERVER_ERROR } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.java deleted file mode 100644 index 79b637bc36..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.openbase.bco.api.graphql.error; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import graphql.ErrorClassification; -import org.openbase.jul.exception.InstantiationException; -import org.openbase.jul.exception.*; - -import javax.crypto.BadPaddingException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeoutException; - -public class GenericError extends BCOGraphQLError { - - private final Throwable initialCause; - - public GenericError(final Throwable cause) { - super(ExceptionProcessor.getInitialCauseMessage(cause), ExceptionProcessor.getInitialCause(cause)); - initialCause = ExceptionProcessor.getInitialCause(getCause()); - } - - @Override - public ErrorClassification getErrorType() { - - // skip if no cause has been set. - if (initialCause == null) { - return ErrorType.SERVER_ERROR; - } - - // compute error type based on initial cause - if (initialCause instanceof TimeoutException - | initialCause instanceof org.openbase.jul.exception.TimeoutException - | initialCause instanceof InterruptedException - | initialCause instanceof FatalImplementationErrorException - | initialCause instanceof NotInitializedException - | initialCause instanceof InstantiationException - | initialCause instanceof InvocationFailedException - | initialCause instanceof ShutdownException - | initialCause instanceof ExecutionException) { - return ErrorType.SERVER_ERROR; - } else if (initialCause instanceof NotAvailableException - | initialCause instanceof VerificationFailedException - | initialCause instanceof InvalidStateException - | initialCause instanceof IllegalArgumentException - | initialCause instanceof NotSupportedException - | initialCause instanceof TypeNotSupportedException - | initialCause instanceof RejectedExecutionException) { - return ErrorType.ARGUMENT_ERROR; - } else if (initialCause instanceof PermissionDeniedException - | initialCause instanceof BadPaddingException) { - return ErrorType.AUTHORIZATION_ERROR; - } else { - return ErrorType.SERVER_ERROR; - } - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.kt new file mode 100644 index 0000000000..cbde1c46e3 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/GenericError.kt @@ -0,0 +1,62 @@ +package org.openbase.bco.api.graphql.error + +import graphql.ErrorClassification +import org.openbase.jul.exception.* +import org.openbase.jul.exception.ExceptionProcessor.getInitialCause +import java.util.concurrent.RejectedExecutionException +import java.util.concurrent.TimeoutException +import javax.crypto.BadPaddingException + + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +class GenericError( + cause: Throwable, +) : BCOGraphQLError(getInitialCause(cause)) { + override fun getErrorType(): ErrorClassification = when (cause) { + is TimeoutException, + is org.openbase.jul.exception.TimeoutException, + is InterruptedException, + is FatalImplementationErrorException, + is NotInitializedException, + is InstantiationException, + is InvocationFailedException, + is ShutdownException, + is java.util.concurrent.ExecutionException, + -> ErrorType.SERVER_ERROR + + is NotAvailableException, + is VerificationFailedException, + is InvalidStateException, + is java.lang.IllegalArgumentException, + is NotSupportedException, + is TypeNotSupportedException, + is RejectedExecutionException, + -> ErrorType.ARGUMENT_ERROR + + is PermissionDeniedException, + is BadPaddingException, + -> ErrorType.AUTHORIZATION_ERROR + + else -> ErrorType.SERVER_ERROR + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.java deleted file mode 100644 index 71d6253e63..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.openbase.bco.api.graphql.error; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import graphql.ErrorClassification; - -import java.util.concurrent.TimeUnit; - -public class ServerError extends BCOGraphQLError { - - public static final long BCO_TIMEOUT_SHORT = 10; - public static final long BCO_TIMEOUT_LONG = 20; - public static final TimeUnit BCO_TIMEOUT_TIME_UNIT = TimeUnit.SECONDS; - - public ServerError(String message) { - this(message, null); - } - - public ServerError(String message, Throwable cause) { - super(message, cause); - } - - public ServerError(final Throwable cause) { - super(cause.getMessage(), cause); - } - - @Override - public ErrorClassification getErrorType() { - return ErrorType.SERVER_ERROR; - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.kt new file mode 100644 index 0000000000..8a8d537955 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/error/ServerError.kt @@ -0,0 +1,40 @@ +package org.openbase.bco.api.graphql.error + +import graphql.ErrorClassification +import java.util.concurrent.TimeUnit + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class ServerError : BCOGraphQLError { + @JvmOverloads + constructor(message: String?, cause: Throwable) : super(cause) + constructor(cause: Throwable) : super(cause) + + override fun getErrorType(): ErrorClassification { + return ErrorType.SERVER_ERROR + } + + companion object { + const val BCO_TIMEOUT_SHORT: Long = 10 + const val BCO_TIMEOUT_LONG: Long = 20 + val BCO_TIMEOUT_TIME_UNIT = TimeUnit.SECONDS + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.java deleted file mode 100644 index 379d1cea14..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.openbase.bco.api.graphql.handler; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import graphql.ExceptionWhileDataFetching; -import graphql.GraphQLError; -import graphql.kickstart.execution.error.GraphQLErrorHandler; -import org.openbase.bco.api.graphql.error.ArgumentError; -import org.openbase.bco.api.graphql.error.BCOGraphQLError; -import org.openbase.bco.api.graphql.error.ErrorType; -import org.openbase.bco.api.graphql.error.ServerError; -import org.openbase.jul.exception.printer.ExceptionPrinter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -@Component -class CustomGraphQlErrorHandler implements GraphQLErrorHandler { - - private final Logger logger = LoggerFactory.getLogger(GraphQLErrorHandler.class); - - @Override - public List processErrors(List list) { - final List errors = new ArrayList<>(); - for (final GraphQLError error : list) { - if (!(error instanceof ExceptionWhileDataFetching)) { - errors.add(error); - continue; - } - - final ExceptionWhileDataFetching dataFetchingError = (ExceptionWhileDataFetching) error; - final Throwable cause = dataFetchingError.getException().getCause(); - - // create as server error if the cause is not a bco graphql error - final BCOGraphQLError bcoError = (cause instanceof BCOGraphQLError) ? ((BCOGraphQLError) cause) : new ServerError(dataFetchingError.getMessage(), cause); - - // update argument error fields - if (bcoError.getErrorType() == ErrorType.ARGUMENT_ERROR) { - bcoError.setLocations(dataFetchingError.getLocations()); - bcoError.setPath(dataFetchingError.getPath()); - } - - // print server errors - if (bcoError.getErrorType() == ErrorType.SERVER_ERROR) { - ExceptionPrinter.printHistory(bcoError, logger); - } - - errors.add(bcoError); - } - return errors; - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.kt new file mode 100644 index 0000000000..ac13a23ecd --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/handler/CustomGraphQlErrorHandler.kt @@ -0,0 +1,57 @@ +package org.openbase.bco.api.graphql.handler + +import graphql.ExceptionWhileDataFetching +import graphql.GraphQLError +import graphql.kickstart.execution.error.GraphQLErrorHandler +import org.openbase.bco.api.graphql.error.BCOGraphQLError +import org.openbase.bco.api.graphql.error.ErrorType +import org.openbase.bco.api.graphql.error.ServerError +import org.openbase.jul.exception.printer.ExceptionPrinter +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */@Component +internal class CustomGraphQlErrorHandler : GraphQLErrorHandler { + private val logger = LoggerFactory.getLogger(GraphQLErrorHandler::class.java) + override fun processErrors(list: List): List = list.mapNotNull { error -> + if (error !is ExceptionWhileDataFetching) { + return@mapNotNull error + } + val cause = error.exception.cause ?: error.exception + + // create as server error if the cause is not a bco graphql error + val bcoError = if (cause is BCOGraphQLError) cause else ServerError(error.message, cause) + + // update argument error fields + if (bcoError.errorType === ErrorType.ARGUMENT_ERROR) { + bcoError.setLocations(error.locations) + bcoError.setPath(error.path) + } + + // print server errors + if (bcoError.errorType === ErrorType.SERVER_ERROR) { + ExceptionPrinter.printHistory(bcoError, logger) + } + bcoError + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java deleted file mode 100644 index 08dd05edaf..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.java +++ /dev/null @@ -1,273 +0,0 @@ -package org.openbase.bco.api.graphql.schema; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import com.google.api.graphql.rejoiner.Arg; -import com.google.api.graphql.rejoiner.Mutation; -import com.google.api.graphql.rejoiner.Query; -import com.google.api.graphql.rejoiner.SchemaModule; -import com.google.common.collect.ImmutableList; -import graphql.schema.DataFetchingEnvironment; -import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext; -import org.openbase.bco.api.graphql.error.ArgumentError; -import org.openbase.bco.api.graphql.error.BCOGraphQLError; -import org.openbase.bco.api.graphql.error.GenericError; -import org.openbase.bco.api.graphql.error.ServerError; -import org.openbase.bco.authentication.lib.SessionManager; -import org.openbase.bco.authentication.lib.future.AuthenticatedValueFuture; -import org.openbase.bco.authentication.lib.iface.BCOSession; -import org.openbase.bco.registry.remote.Registries; -import org.openbase.bco.registry.remote.session.BCOSessionImpl; -import org.openbase.bco.registry.unit.remote.UnitRegistryRemote; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor; -import org.openbase.jul.extension.type.processing.LabelProcessor; -import org.openbase.type.configuration.EntryType; -import org.openbase.type.configuration.MetaConfigType; -import org.openbase.type.domotic.authentication.AuthTokenType.AuthToken; -import org.openbase.type.domotic.authentication.AuthenticatedValueType.AuthenticatedValue; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter; -import org.openbase.type.domotic.unit.gateway.GatewayClassType.GatewayClass; -import org.openbase.type.geometry.PoseType; -import org.openbase.type.language.LabelType; -import org.openbase.type.spatial.PlacementConfigType; -import org.openbase.type.spatial.ShapeType; - -import java.util.Base64; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; - -public class RegistrySchemaModule extends SchemaModule { - - // ===================================== Queries =================================================================== - - public static ImmutableList getUnitConfigs(final UnitFilter unitFilter, Boolean includeDisabledUnits) throws BCOGraphQLError { - try { - if ((includeDisabledUnits == null)) { - includeDisabledUnits = false; - } - return ImmutableList.copyOf( - Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigs(includeDisabledUnits, unitFilter)); - - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - /** - * Check if an authentication token retrieved by the login method is still valid. - * - * @param token the token to be checked - * - * @return if the token is valid and can be used to authenticate further requests - */ - @Query("verifyToken") - Boolean verifyToken(@Arg("token") String token) { - //TODO: blocked by https://github.com/openbase/bco.registry/issues/108 - return true; - } - - /** - * Method can be used to request a token of the given bco user. - * - * @param username the name of the user as plain text string. - * @param passwordHash the password hash of the user that need to be generted first (see note below). - * - * @return the login token. - *

- * Note: The hash of the default admin password is: '''R+gZ+PFuauhav8rRVa3XlWXXSEyi5BcdrbeXLEY3tDQ=''' - * - * @throws BCOGraphQLError - */ - @Query("login") - String login(@Arg("username") String username, @Arg("password") String passwordHash) throws BCOGraphQLError { - try { - final BCOSession session = new BCOSessionImpl(); - - session.loginUserViaUsername(username, Base64.getDecoder().decode(passwordHash), false); - return session.generateAuthToken(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getAuthenticationToken(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Query("changePassword") - Boolean changePassword(@Arg("username") String username, @Arg("oldPassword") String oldPassword, @Arg("newPassword") String newPassword) throws BCOGraphQLError { - try { - final String userId = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUserUnitIdByUserName(username); - - final SessionManager sessionManager = new SessionManager(); - try { - sessionManager.loginUser(userId, oldPassword, false); - } catch (CouldNotPerformException ex) { - throw new ArgumentError(ex); - } - sessionManager.changePassword(userId, oldPassword, newPassword).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - - return true; - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Query("unitConfig") - UnitConfig getUnitConfigById(@Arg("id") String id, DataFetchingEnvironment env) throws BCOGraphQLError { - try { - return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(id); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - @Query("unitConfigs") - ImmutableList queryGetUnitConfigs(@Arg("filter") UnitFilter unitFilter, @Arg("includeDisabledUnits") Boolean includeDisabledUnits) throws BCOGraphQLError { - return getUnitConfigs(unitFilter, includeDisabledUnits); - } - - // ===================================== Mutations ================================================================= - - @Query("gatewayClasses") - ImmutableList gatewayClasses() throws CouldNotPerformException, InterruptedException { - return ImmutableList.copyOf(Registries.getClassRegistry(true).getGatewayClasses()); - } - - @Mutation("updateUnitConfig") - UnitConfig updateUnitConfig(@Arg("unitConfig") UnitConfig unitConfig) throws BCOGraphQLError { - try { - final UnitConfig.Builder unitConfigBuilder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT) - .getUnitConfigById(unitConfig.getId()) - .toBuilder(); - ProtoBufBuilderProcessor.mergeFromWithoutRepeatedFields(unitConfigBuilder, unitConfig); - return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).updateUnitConfig(unitConfigBuilder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("removeUnitConfig") - UnitConfig removeUnitConfig(@Arg("unitId") String unitId) throws BCOGraphQLError { - try { - final UnitConfig unitConfig = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId); - return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).removeUnitConfig(unitConfig).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("registerUnitConfig") - UnitConfig registerUnitConfig(@Arg("unitConfig") UnitConfig unitConfig) throws BCOGraphQLError { - try { - return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).registerUnitConfig(unitConfig).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("updateLabel") - LabelType.Label updateLabel(@Arg("unitId") String unitId, @Arg("label") String label, DataFetchingEnvironment env) throws BCOGraphQLError { - try { - final UnitConfig.Builder builder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId).toBuilder(); - - final AbstractBCOGraphQLContext context = env.getContext(); - final String oldLabel = LabelProcessor.getBestMatch(context.getLanguageCode(), builder.getLabel()); - LabelProcessor.replace(builder.getLabelBuilder(), oldLabel, label); - - return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getLabel(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("updateLocation") - PlacementConfigType.PlacementConfig updateLocation(@Arg("unitId") String unitId, @Arg("locationId") String locationId) throws BCOGraphQLError { - try { - final UnitConfig.Builder builder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId).toBuilder(); - builder.getPlacementConfigBuilder().setLocationId(locationId); - return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("updateFloorPlan") - ShapeType.Shape updateFloorPlan(@Arg("locationId") String locationId, @Arg("shape") ShapeType.Shape shape) throws BCOGraphQLError { - try { - final UnitConfig.Builder unitConfigBuilder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(locationId).toBuilder(); - unitConfigBuilder.getPlacementConfigBuilder().getShapeBuilder().clearFloor().addAllFloor(shape.getFloorList()); - return Registries.getUnitRegistry().updateUnitConfig(unitConfigBuilder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig().getShape(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - @Mutation("updatePose") - PoseType.Pose updatePose(@Arg("unitId") String unitId, @Arg("pose") PoseType.Pose pose) throws BCOGraphQLError { - try { - final UnitConfig.Builder builder = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(unitId).toBuilder(); - builder.getPlacementConfigBuilder().clearPose().setPose(pose); - return Registries.getUnitRegistry().updateUnitConfig(builder.build()).get(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getPlacementConfig().getPose(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException | - TimeoutException ex) { - throw new GenericError(ex); - } - } - - // ===================================== Service Methods =========================================================== - - @Mutation("updateMetaConfig") - MetaConfigType.MetaConfig updateMetaConfig(@Arg("unitId") String unitId, @Arg("entry") EntryType.Entry entry, DataFetchingEnvironment env) throws BCOGraphQLError { - try { - final UnitRegistryRemote unitRegistry = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - - final UnitConfig.Builder unitConfigBuilder = unitRegistry.getUnitConfigById(unitId).toBuilder(); - final MetaConfigType.MetaConfig.Builder metaConfigBuilder = unitConfigBuilder.getMetaConfigBuilder(); - for (int i = 0; i < metaConfigBuilder.getEntryCount(); i++) { - if (metaConfigBuilder.getEntry(i).getKey().equals(entry.getKey())) { - metaConfigBuilder.removeEntry(i); - break; - } - } - if (!entry.getValue().isEmpty()) { - metaConfigBuilder.addEntry(entry); - } - - final SessionManager sessionManager = SessionManager.getInstance(); - final AuthToken authToken = AuthToken.newBuilder().setAuthenticationToken(((AbstractBCOGraphQLContext) env.getContext()).getToken()).build(); - final AuthenticatedValue request = sessionManager.initializeRequest(unitConfigBuilder.build(), authToken); - final Future future = unitRegistry.updateUnitConfigAuthenticated(request); - final AuthenticatedValueFuture authFuture = new AuthenticatedValueFuture(future, UnitConfig.class, request.getTicketAuthenticatorWrapper(), sessionManager); - return authFuture.get().getMetaConfig(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException | ExecutionException ex) { - throw new GenericError(ex); - } - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt new file mode 100644 index 0000000000..b402e48190 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt @@ -0,0 +1,427 @@ +package org.openbase.bco.api.graphql.schema + +import com.google.api.graphql.rejoiner.* +import com.google.common.collect.ImmutableList +import graphql.schema.DataFetchingEnvironment +import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext +import org.openbase.bco.api.graphql.error.ArgumentError +import org.openbase.bco.api.graphql.error.BCOGraphQLError +import org.openbase.bco.api.graphql.error.GenericError +import org.openbase.bco.api.graphql.error.ServerError +import org.openbase.bco.authentication.lib.SessionManager +import org.openbase.bco.authentication.lib.future.AuthenticatedValueFuture +import org.openbase.bco.authentication.lib.iface.BCOSession +import org.openbase.bco.registry.remote.Registries +import org.openbase.bco.registry.remote.session.BCOSessionImpl +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor.mergeFromWithoutRepeatedFields +import org.openbase.jul.extension.type.processing.LabelProcessor.getBestMatch +import org.openbase.jul.extension.type.processing.LabelProcessor.replace +import org.openbase.type.configuration.EntryType +import org.openbase.type.configuration.MetaConfigType +import org.openbase.type.domotic.authentication.AuthTokenType +import org.openbase.type.domotic.unit.UnitConfigType +import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig +import org.openbase.type.domotic.unit.UnitFilterType +import org.openbase.type.domotic.unit.gateway.GatewayClassType +import org.openbase.type.geometry.PoseType +import org.openbase.type.language.LabelType +import org.openbase.type.spatial.PlacementConfigType +import org.openbase.type.spatial.ShapeType +import java.util.* +import java.util.concurrent.* + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class RegistrySchemaModule : SchemaModule() { + /** + * Check if an authentication token retrieved by the login method is still valid. + * + * @param token the token to be checked + * + * @return if the token is valid and can be used to authenticate further requests + */ + @Query("verifyToken") + fun verifyToken(@Arg("token") token: String?): java.lang.Boolean { + TODO("blocked by https://github.com/openbase/bco.registry/issues/108") + } + + /** + * Method can be used to request a token of the given bco user. + * + * @param username the name of the user as plain text string. + * @param passwordHash the password hash of the user that need to be generted first (see note below). + * + * @return the login token. + * + * + * Note: The hash of the default admin password is: '''R+gZ+PFuauhav8rRVa3XlWXXSEyi5BcdrbeXLEY3tDQ=''' + * + * @throws BCOGraphQLError + */ + @Query("login") + @Throws(BCOGraphQLError::class) + fun login(@Arg("username") username: String?, @Arg("password") passwordHash: String?): String { + return try { + val session: BCOSession = BCOSessionImpl() + session.loginUserViaUsername(username, Base64.getDecoder().decode(passwordHash), false) + session.generateAuthToken( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).authenticationToken + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Query("changePassword") + @Throws(BCOGraphQLError::class) + fun changePassword( + @Arg("username") username: String?, + @Arg("oldPassword") oldPassword: String?, + @Arg("newPassword") newPassword: String?, + ): String { + try { + val userId = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUserUnitIdByUserName(username) + val sessionManager = SessionManager() + try { + sessionManager.loginUser(userId, oldPassword, false) + } catch (ex: CouldNotPerformException) { + throw ArgumentError(ex) + } + sessionManager.changePassword( + userId, + oldPassword, + newPassword + )[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + return "läuft" + } + + @Query("unitConfig") + @Throws(BCOGraphQLError::class) + fun getUnitConfigById(@Arg("id") id: String?, env: DataFetchingEnvironment?): UnitConfigType.UnitConfig { + return try { + Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(id) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + @Query("unitConfigs") + @Throws(BCOGraphQLError::class) + fun queryGetUnitConfigs( + @Arg("filter") unitFilter: UnitFilterType.UnitFilter?, + @Arg("includeDisabledUnits") includeDisabledUnits: Boolean?, + ): ImmutableList { + return getUnitConfigs(unitFilter, includeDisabledUnits) + } + + // ===================================== Mutations ================================================================= + @Query("gatewayClasses") + @Throws(CouldNotPerformException::class, InterruptedException::class) + fun gatewayClasses(): ImmutableList { + return ImmutableList.copyOf(Registries.getClassRegistry(true).gatewayClasses) + } + + @Mutation("updateUnitConfig") + @Throws(BCOGraphQLError::class) + fun updateUnitConfig(@Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig): UnitConfigType.UnitConfig { + return try { + val unitConfigBuilder = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + .getUnitConfigById(unitConfig.id) + .toBuilder() + unitConfigBuilder.mergeFromWithoutRepeatedFields(unitConfig) + Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + .updateUnitConfig(unitConfigBuilder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("removeUnitConfig") + @Throws(BCOGraphQLError::class) + fun removeUnitConfig(@Arg("unitId") unitId: String?): UnitConfigType.UnitConfig { + return try { + val unitConfig = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId) + Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + .removeUnitConfig(unitConfig)[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("registerUnitConfig") + @Throws(BCOGraphQLError::class) + fun registerUnitConfig(@Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig?): UnitConfigType.UnitConfig { + return try { + Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + .registerUnitConfig(unitConfig)[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("updateLabel") + @Throws(BCOGraphQLError::class) + fun updateLabel( + @Arg("unitId") unitId: String?, + @Arg("label") label: String?, + env: DataFetchingEnvironment, + ): LabelType.Label { + return try { + val builder = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + val context = env.getContext() + val oldLabel = getBestMatch(context.languageCode, builder.label) + replace(builder.labelBuilder, oldLabel, label) + Registries.getUnitRegistry() + .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].label + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("updateLocation") + @Throws(BCOGraphQLError::class) + fun updateLocation( + @Arg("unitId") unitId: String?, + @Arg("locationId") locationId: String?, + ): PlacementConfigType.PlacementConfig { + return try { + val builder = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + builder.placementConfigBuilder.locationId = locationId + Registries.getUnitRegistry() + .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("updateFloorPlan") + @Throws(BCOGraphQLError::class) + fun updateFloorPlan(@Arg("locationId") locationId: String?, @Arg("shape") shape: ShapeType.Shape): ShapeType.Shape { + return try { + val unitConfigBuilder = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(locationId).toBuilder() + unitConfigBuilder.placementConfigBuilder.shapeBuilder.clearFloor().addAllFloor(shape.floorList) + Registries.getUnitRegistry() + .updateUnitConfig(unitConfigBuilder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig.shape + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + @Mutation("updatePose") + @Throws(BCOGraphQLError::class) + fun updatePose(@Arg("unitId") unitId: String?, @Arg("pose") pose: PoseType.Pose?): PoseType.Pose { + return try { + val builder = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + builder.placementConfigBuilder.clearPose().pose = pose + Registries.getUnitRegistry() + .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig.pose + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + } + } + + // ===================================== Service Methods =========================================================== + @Mutation("updateMetaConfig") + @Throws(BCOGraphQLError::class) + fun updateMetaConfig( + @Arg("unitId") unitId: String?, + @Arg("entry") entry: EntryType.Entry, + env: DataFetchingEnvironment, + ): MetaConfigType.MetaConfig { + return try { + val unitRegistry = Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + val unitConfigBuilder = unitRegistry.getUnitConfigById(unitId).toBuilder() + val metaConfigBuilder = unitConfigBuilder.metaConfigBuilder + for (i in 0 until metaConfigBuilder.entryCount) { + if (metaConfigBuilder.getEntry(i).key == entry.key) { + metaConfigBuilder.removeEntry(i) + break + } + } + if (!entry.value.isEmpty()) { + metaConfigBuilder.addEntry(entry) + } + val sessionManager = SessionManager.getInstance() + val authToken = AuthTokenType.AuthToken.newBuilder() + .setAuthenticationToken((env.getContext() as AbstractBCOGraphQLContext).token).build() + val request = sessionManager.initializeRequest(unitConfigBuilder.build(), authToken) + val future = unitRegistry.updateUnitConfigAuthenticated(request) + val authFuture: AuthenticatedValueFuture = AuthenticatedValueFuture( + future, + UnitConfig::class.java, + request.ticketAuthenticatorWrapper, + sessionManager + ) + authFuture.get()!!.metaConfig + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } + } + + companion object { + // ===================================== Queries =================================================================== + @Throws(BCOGraphQLError::class) + fun getUnitConfigs( + unitFilter: UnitFilterType.UnitFilter?, + includeDisabledUnits: Boolean?, + ): ImmutableList { + var includeDisabledUnits: Boolean? = includeDisabledUnits + return try { + if (includeDisabledUnits == null) { + includeDisabledUnits = true + } + ImmutableList.copyOf( + Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigs(includeDisabledUnits, unitFilter) + ) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.kt similarity index 100% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.java rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.kt diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.java deleted file mode 100644 index 66b4cacefd..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.openbase.bco.api.graphql.schema; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import com.google.api.graphql.rejoiner.*; -import com.google.common.collect.ImmutableList; -import com.google.protobuf.Message; -import graphql.schema.DataFetchingEnvironment; -import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext; -import org.openbase.bco.api.graphql.error.BCOGraphQLError; -import org.openbase.bco.api.graphql.error.GenericError; -import org.openbase.bco.api.graphql.error.ServerError; -import org.openbase.bco.dal.lib.action.ActionDescriptionProcessor; -import org.openbase.bco.dal.lib.layer.service.Services; -import org.openbase.bco.dal.lib.layer.unit.UnitRemote; -import org.openbase.bco.dal.remote.action.RemoteAction; -import org.openbase.bco.dal.remote.layer.unit.Units; -import org.openbase.bco.registry.remote.Registries; -import org.openbase.bco.registry.unit.lib.filter.UnitConfigFilterImpl; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.exception.NotAvailableException; -import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor; -import org.openbase.jul.pattern.ListFilter; -import org.openbase.type.domotic.action.ActionParameterType.ActionParameter; -import org.openbase.type.domotic.authentication.AuthTokenType.AuthToken; -import org.openbase.type.domotic.service.ServiceTemplateType.ServiceTemplate.ServiceType; -import org.openbase.type.domotic.service.ServiceTempusTypeType.ServiceTempusType.ServiceTempus; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.unit.UnitDataType.UnitData; -import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class UnitSchemaModule extends SchemaModule { - - // ===================================== Schema Modifications ====================================================== - - @SchemaModification(addField = "config", onType = UnitData.class) - UnitConfig addConfigToData(UnitData data) throws CouldNotPerformException, InterruptedException { - return Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigById(data.getId()); - } - - // ===================================== Queries =================================================================== - - @Query("unit") - UnitData unit(@Arg("unitId") String id) throws BCOGraphQLError { - try { - final UnitRemote unit = Units.getUnit(id, ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - return (UnitData) ProtoBufBuilderProcessor.merge(UnitData.newBuilder(), unit.getData()).build(); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - @Query("units") - ImmutableList units(@Arg("filter") UnitFilter unitFilter) throws BCOGraphQLError { - try { - final List dataList = new ArrayList<>(); - for (UnitConfig unitConfig : Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigs(unitFilter)) { - UnitRemote unit = Units.getUnit(unitConfig, ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - dataList.add((UnitData) ProtoBufBuilderProcessor.merge(UnitData.newBuilder(), unit.getData()).build()); - } - return ImmutableList.copyOf(dataList); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - // ===================================== Queries =================================================================== - - @Mutation("unit") - UnitData unit(@Arg("unitId") String unitId, @Arg("data") UnitData data, DataFetchingEnvironment env) throws BCOGraphQLError { - try { - return setServiceStates(unitId, data, env, ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - @Mutation("units") - ImmutableList units(@Arg("filter") UnitFilter unitFilter, @Arg("data") UnitData data, DataFetchingEnvironment env) throws BCOGraphQLError { - try { - final List dataList = new ArrayList<>(); - for (UnitConfig unitConfig : Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT).getUnitConfigs(unitFilter)) { - dataList.add(setServiceStates(unitConfig, data, env, ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT)); - } - return ImmutableList.copyOf(dataList); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - // ===================================== Service Methods =========================================================== - - private UnitData setServiceStates(final UnitConfig unitConfig, final UnitData data, DataFetchingEnvironment env, final long timeout, final TimeUnit timeUnit) throws CouldNotPerformException, InterruptedException { - return setServiceStates(unitConfig.getId(), data, env, timeout, timeUnit); - } - - private UnitData setServiceStates(final String unitId, final UnitData data, DataFetchingEnvironment env, final long timeout, final TimeUnit timeUnit) throws CouldNotPerformException, InterruptedException { - final UnitRemote unit = Units.getUnit(unitId, timeout, timeUnit); - - final List remoteActions = new ArrayList<>(); - for (final ServiceType serviceType : unit.getSupportedServiceTypes()) { - - if (!Services.hasServiceState(serviceType, ServiceTempus.CURRENT, data)) { - continue; - } - - final Message serviceState = Services.invokeProviderServiceMethod(serviceType, data); - - final ActionParameter.Builder builder = ActionDescriptionProcessor.generateDefaultActionParameter(serviceState, serviceType, unit); - try { - builder.setAuthToken(AuthToken.newBuilder().setAuthenticationToken(((AbstractBCOGraphQLContext) env.getContext()).getToken()).build()); - } catch (NotAvailableException ex) { - // in case the auth token is not available, we just continue without any authentication. - } - remoteActions.add(new RemoteAction(unit.applyAction(builder), builder.getAuthToken())); - } - - UnitData.Builder unitDataBuilder = UnitData.newBuilder(); - // TODO: blocked by https://github.com/openbase/bco.dal/issues/170 - if (!remoteActions.isEmpty()) { - for (final RemoteAction remoteAction : remoteActions) { - remoteAction.waitForRegistration(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - unitDataBuilder.addTriggeredAction(remoteAction.getActionDescription()); - } - } - - ProtoBufBuilderProcessor.merge(unitDataBuilder, unit.getData()); - return unitDataBuilder.build(); - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt new file mode 100644 index 0000000000..fa07311c9d --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt @@ -0,0 +1,214 @@ +package org.openbase.bco.api.graphql.schema + +import com.google.api.graphql.rejoiner.* +import com.google.common.collect.ImmutableList +import graphql.schema.DataFetchingEnvironment +import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext +import org.openbase.bco.api.graphql.error.BCOGraphQLError +import org.openbase.bco.api.graphql.error.GenericError +import org.openbase.bco.api.graphql.error.ServerError +import org.openbase.bco.dal.lib.action.ActionDescriptionProcessor +import org.openbase.bco.dal.lib.layer.service.Services +import org.openbase.bco.dal.remote.action.RemoteAction +import org.openbase.bco.dal.remote.layer.unit.Units +import org.openbase.bco.registry.remote.Registries +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.exception.NotAvailableException +import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor.merge +import org.openbase.type.domotic.authentication.AuthTokenType +import org.openbase.type.domotic.service.ServiceTempusTypeType +import org.openbase.type.domotic.unit.UnitConfigType +import org.openbase.type.domotic.unit.UnitDataType +import org.openbase.type.domotic.unit.UnitFilterType +import java.util.concurrent.TimeUnit + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ class UnitSchemaModule : SchemaModule() { + // ===================================== Schema Modifications ====================================================== + @SchemaModification(addField = "config", onType = UnitDataType.UnitData::class) + @Throws( + CouldNotPerformException::class, InterruptedException::class + ) + fun addConfigToData(data: UnitDataType.UnitData): UnitConfigType.UnitConfig { + return Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(data.id) + } + + // ===================================== Queries =================================================================== + @Query("unit") + @Throws(BCOGraphQLError::class) + fun unit(@Arg("unitId") id: String?): UnitDataType.UnitData { + return try { + val unit = + Units.getUnit(id, ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT) + merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + @Query("units") + @Throws(BCOGraphQLError::class) + fun units(@Arg("filter") unitFilter: UnitFilterType.UnitFilter?): ImmutableList { + return try { + val dataList: MutableList = ArrayList() + for (unitConfig in Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigs(unitFilter)) { + val unit = Units.getUnit( + unitConfig, + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + dataList.add(merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData) + } + ImmutableList.copyOf(dataList) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + // ===================================== Queries =================================================================== + @Mutation("unit") + @Throws(BCOGraphQLError::class) + fun unit( + @Arg("unitId") unitId: String, + @Arg("data") data: UnitDataType.UnitData, + env: DataFetchingEnvironment + ): UnitDataType.UnitData { + return try { + setServiceStates( + unitId, + data, + env, + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + @Mutation("units") + @Throws(BCOGraphQLError::class) + fun units( + @Arg("filter") unitFilter: UnitFilterType.UnitFilter?, + @Arg("data") data: UnitDataType.UnitData, + env: DataFetchingEnvironment + ): ImmutableList { + return try { + val dataList: MutableList = ArrayList() + for (unitConfig in Registries.getUnitRegistry( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigs(unitFilter)) { + dataList.add( + setServiceStates( + unitConfig, + data, + env, + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + ) + } + ImmutableList.copyOf(dataList) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + // ===================================== Service Methods =========================================================== + @Throws(CouldNotPerformException::class, InterruptedException::class) + private fun setServiceStates( + unitConfig: UnitConfigType.UnitConfig, + data: UnitDataType.UnitData, + env: DataFetchingEnvironment, + timeout: Long, + timeUnit: TimeUnit + ): UnitDataType.UnitData { + return setServiceStates(unitConfig.id, data, env, timeout, timeUnit) + } + + @Throws(CouldNotPerformException::class, InterruptedException::class) + private fun setServiceStates( + unitId: String, + data: UnitDataType.UnitData, + env: DataFetchingEnvironment, + timeout: Long, + timeUnit: TimeUnit + ): UnitDataType.UnitData { + val unit = Units.getUnit(unitId, timeout, timeUnit) + val remoteActions: MutableList = ArrayList() + for (serviceType in unit.supportedServiceTypes) { + if (!Services.hasServiceState( + serviceType, + ServiceTempusTypeType.ServiceTempusType.ServiceTempus.CURRENT, + data + ) + ) { + continue + } + val serviceState = Services.invokeProviderServiceMethod(serviceType, data) + val builder = ActionDescriptionProcessor.generateDefaultActionParameter(serviceState, serviceType, unit) + try { + builder.authToken = AuthTokenType.AuthToken.newBuilder() + .setAuthenticationToken((env.getContext() as AbstractBCOGraphQLContext).token).build() + } catch (ex: NotAvailableException) { + // in case the auth token is not available, we just continue without any authentication. + } + remoteActions.add(RemoteAction(unit.applyAction(builder), builder.authToken)) + } + val unitDataBuilder = UnitDataType.UnitData.newBuilder() + // TODO: blocked by https://github.com/openbase/bco.dal/issues/170 + if (!remoteActions.isEmpty()) { + for (remoteAction in remoteActions) { + remoteAction.waitForRegistration( + ServerError.Companion.BCO_TIMEOUT_SHORT, + ServerError.Companion.BCO_TIMEOUT_TIME_UNIT + ) + unitDataBuilder.addTriggeredAction(remoteAction.actionDescription) + } + } + merge(unitDataBuilder, unit.data) + return unitDataBuilder.build() + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.java deleted file mode 100644 index 01c5f1ae11..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.openbase.bco.api.graphql.subscriptions; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import io.reactivex.Observable; -import io.reactivex.ObservableEmitter; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.pattern.Observer; - -import java.util.function.Consumer; - -public abstract class AbstractObserverMapper implements Observer { - - private ObservableEmitter emitter = null; - - @Override - public void update(final S source, T target) throws Exception { - if (emitter == null) { - return; - } - - emitter.onNext(mapData(source, target)); - } - - public void setEmitter(final ObservableEmitter emitter) { - this.emitter = emitter; - } - - public abstract E mapData(final S source, final T data) throws Exception; - - public void doAfterRemoveObserver() throws CouldNotPerformException { - } - - public void doAfterAddObserver() throws CouldNotPerformException, InterruptedException { - } - - public static Observable createObservable(Consumer> addObserver, Consumer> removeObserver, AbstractObserverMapper obs) { - Observable observable = Observable.create(emitter -> { - obs.setEmitter(emitter); - addObserver.accept(obs); - obs.doAfterAddObserver(); - }); - - observable = observable.doOnDispose(() -> { - removeObserver.accept(obs); - obs.doAfterRemoveObserver(); - }); - - return observable; - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.kt new file mode 100644 index 0000000000..a8230f6d6c --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/AbstractObserverMapper.kt @@ -0,0 +1,71 @@ +package org.openbase.bco.api.graphql.subscriptions + +import io.reactivex.Observable +import io.reactivex.ObservableEmitter +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.pattern.Observer +import java.util.function.Consumer + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ abstract class AbstractObserverMapper : Observer { + private var emitter: ObservableEmitter? = null + @Throws(Exception::class) + override fun update(source: S, target: T) { + if (emitter == null) { + return + } + emitter!!.onNext(mapData(source, target)) + } + + fun setEmitter(emitter: ObservableEmitter?) { + this.emitter = emitter + } + + @Throws(Exception::class) + abstract fun mapData(source: S, data: T): E + @Throws(CouldNotPerformException::class) + open fun doAfterRemoveObserver() { + } + + @Throws(CouldNotPerformException::class, InterruptedException::class) + open fun doAfterAddObserver() { + } + + companion object { + fun createObservable( + addObserver: Consumer>, + removeObserver: Consumer>, + obs: AbstractObserverMapper + ): Observable { + var observable = Observable.create { emitter: ObservableEmitter? -> + obs.setEmitter(emitter) + addObserver.accept(obs) + obs.doAfterAddObserver() + } + observable = observable.doOnDispose { + removeObserver.accept(obs) + obs.doAfterRemoveObserver() + } + return observable + } + } +} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.java b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.java deleted file mode 100644 index d0fee30a07..0000000000 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.openbase.bco.api.graphql.subscriptions; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -import com.google.common.collect.ImmutableList; -import com.google.protobuf.Message; -import io.reactivex.BackpressureStrategy; -import lombok.extern.slf4j.Slf4j; -import org.openbase.bco.api.graphql.error.BCOGraphQLError; -import org.openbase.bco.api.graphql.error.GenericError; -import org.openbase.bco.api.graphql.error.ServerError; -import org.openbase.bco.api.graphql.schema.RegistrySchemaModule; -import org.openbase.bco.dal.lib.layer.service.ServiceStateProvider; -import org.openbase.bco.dal.lib.layer.unit.Unit; -import org.openbase.bco.dal.lib.layer.unit.UnitRemote; -import org.openbase.bco.dal.remote.layer.unit.CustomUnitPool; -import org.openbase.bco.dal.remote.layer.unit.Units; -import org.openbase.bco.registry.remote.Registries; -import org.openbase.bco.registry.unit.remote.UnitRegistryRemote; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor; -import org.openbase.jul.pattern.provider.DataProvider; -import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.unit.UnitDataType; -import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter; -import org.reactivestreams.Publisher; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -public class SubscriptionModule { - - private static final org.slf4j.Logger log = LoggerFactory.getLogger(SubscriptionModule.class); - - //TODO: what is a good strategy here - private static BackpressureStrategy BACKPRESSURE_STRATEGY = BackpressureStrategy.BUFFER; - - public static Publisher subscribeUnits(final UnitFilter unitFilter) throws BCOGraphQLError { - try { - final CustomUnitPool subscriptionUnitPool = new CustomUnitPool(); - subscriptionUnitPool.init(unitFilter); - - return AbstractObserverMapper.createObservable( - subscriptionUnitPool::addDataObserver, - subscriptionUnitPool::removeDataObserver, - new AbstractObserverMapper, Message, UnitDataType.UnitData>() { - @Override - public UnitDataType.UnitData mapData(Unit source, Message data) { - return (UnitDataType.UnitData) ProtoBufBuilderProcessor.merge(UnitDataType.UnitData.newBuilder(), data).build(); - } - - @Override - public void doAfterAddObserver() throws CouldNotPerformException, InterruptedException { - subscriptionUnitPool.activate(); - for (UnitRemote unitRemote : subscriptionUnitPool.getInternalUnitList()) { - log.debug("Subscribe to: "+unitRemote); - } - } - - @Override - public void doAfterRemoveObserver() { - subscriptionUnitPool.shutdown(); - } - }).toFlowable(BACKPRESSURE_STRATEGY); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - public static Publisher> subscribeUnitConfigs(final UnitFilter unitFilter, boolean includeDisabledUnits) throws BCOGraphQLError { - try { - final RegistrySubscriptionObserver observer = new RegistrySubscriptionObserver(unitFilter, includeDisabledUnits); - final UnitRegistryRemote unitRegistry = Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - return AbstractObserverMapper.createObservable(unitRegistry::addDataObserver, unitRegistry::removeDataObserver, - observer).toFlowable(BACKPRESSURE_STRATEGY); - } catch (RuntimeException | CouldNotPerformException | InterruptedException ex) { - throw new GenericError(ex); - } - } - - public static class RegistrySubscriptionObserver extends AbstractObserverMapper, UnitRegistryData, List> { - - private final boolean includeDisabledUnits; - private final UnitFilter unitFilter; - private final List unitConfigs; - - public RegistrySubscriptionObserver(final UnitFilter unitFilter, boolean includeDisabledUnits) throws CouldNotPerformException, InterruptedException, BCOGraphQLError { - this.unitFilter = unitFilter; - this.includeDisabledUnits = includeDisabledUnits; - - Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT); - this.unitConfigs = new ArrayList<>(RegistrySchemaModule.getUnitConfigs(unitFilter, includeDisabledUnits)); - } - - @Override - public void update(DataProvider source, UnitRegistryData target) throws Exception { - final ImmutableList newUnitConfigs = RegistrySchemaModule.getUnitConfigs(unitFilter, includeDisabledUnits); - - if (newUnitConfigs.equals(unitConfigs)) { - // nothing has changed - return; - } - - // store update - unitConfigs.clear(); - unitConfigs.addAll(newUnitConfigs); - - super.update(source, target); - } - - @Override - public List mapData(DataProvider source, UnitRegistryData data) throws Exception { - return this.unitConfigs; - } - } -} diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.kt new file mode 100644 index 0000000000..17e154c215 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/subscriptions/SubscriptionModule.kt @@ -0,0 +1,168 @@ +package org.openbase.bco.api.graphql.subscriptions + +import com.google.common.collect.ImmutableList +import com.google.protobuf.Message +import io.reactivex.BackpressureStrategy +import org.openbase.bco.api.graphql.error.BCOGraphQLError +import org.openbase.bco.api.graphql.error.GenericError +import org.openbase.bco.api.graphql.error.ServerError +import org.openbase.bco.api.graphql.schema.RegistrySchemaModule +import org.openbase.bco.dal.lib.layer.unit.Unit +import org.openbase.bco.dal.remote.layer.unit.CustomUnitPool +import org.openbase.bco.registry.remote.Registries +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor.merge +import org.openbase.jul.pattern.Observer +import org.openbase.jul.pattern.provider.DataProvider +import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData +import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig +import org.openbase.type.domotic.unit.UnitDataType +import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter +import org.reactivestreams.Publisher +import org.slf4j.LoggerFactory +import java.util.function.Consumer + +/*- + * #%L + * BCO GraphQL API + * %% + * Copyright (C) 2020 openbase.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ object SubscriptionModule { + private val log = LoggerFactory.getLogger(SubscriptionModule::class.java) + + //TODO: what is a good strategy here + private val BACKPRESSURE_STRATEGY = BackpressureStrategy.BUFFER + + @Throws(BCOGraphQLError::class) + fun subscribeUnits(unitFilter: UnitFilter?): Publisher { + return try { + val subscriptionUnitPool = CustomUnitPool() + subscriptionUnitPool.init(unitFilter) + AbstractObserverMapper.createObservable( + Consumer { observer: Observer, Message> -> + subscriptionUnitPool.addDataObserver( + observer + ) + }, + Consumer { observer: Observer, Message> -> + subscriptionUnitPool.removeDataObserver(observer) + }, + object : AbstractObserverMapper, Message, UnitDataType.UnitData>() { + override fun mapData(source: Unit, data: Message): UnitDataType.UnitData { + return merge(UnitDataType.UnitData.newBuilder(), data!!).build() as UnitDataType.UnitData + } + + @Throws(CouldNotPerformException::class, InterruptedException::class) + override fun doAfterAddObserver() { + subscriptionUnitPool.activate() + for (unitRemote in subscriptionUnitPool.internalUnitList) { + log.debug("Subscribe to: $unitRemote") + } + } + + override fun doAfterRemoveObserver() { + subscriptionUnitPool.shutdown() + } + }).toFlowable(BACKPRESSURE_STRATEGY) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + @Throws(BCOGraphQLError::class) + fun subscribeUnitConfigs( + unitFilter: UnitFilter, + includeDisabledUnits: Boolean, + ): Publisher> { + return try { + val observer = RegistrySubscriptionObserver(unitFilter, includeDisabledUnits) + val unitRegistry = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + AbstractObserverMapper.createObservable( + Consumer { observer: Observer, UnitRegistryData> -> + unitRegistry.addDataObserver( + observer + ) + }, + Consumer { observer: Observer, UnitRegistryData> -> + unitRegistry.removeDataObserver(observer) + }, + observer + ).toFlowable(BACKPRESSURE_STRATEGY) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } + } + + class RegistrySubscriptionObserver( + private val unitFilter: UnitFilter, + private val includeDisabledUnits: Boolean, + ) : AbstractObserverMapper, UnitRegistryData, List>() { + private val unitConfigs: MutableList + + init { + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + unitConfigs = ArrayList( + RegistrySchemaModule.getUnitConfigs( + unitFilter, includeDisabledUnits + ) + ) + } + + @Throws(Exception::class) + override fun update( + source: DataProvider, + target: UnitRegistryData, + ) { + val newUnitConfigs: ImmutableList = + RegistrySchemaModule.getUnitConfigs( + unitFilter, includeDisabledUnits + ) + if (newUnitConfigs == unitConfigs) { + // nothing has changed + return + } + + // store update + unitConfigs.clear() + unitConfigs.addAll(newUnitConfigs) + super.update(source, target) + } + + @Throws(Exception::class) + override fun mapData( + source: DataProvider, + data: UnitRegistryData, + ): List { + return unitConfigs + } + } +} diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/unitgroupconfig/UnitGroupMemberRecursionConsistencyHandler.kt b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/unitgroupconfig/UnitGroupMemberRecursionConsistencyHandler.kt index 02d530f2a6..46286f6e21 100644 --- a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/unitgroupconfig/UnitGroupMemberRecursionConsistencyHandler.kt +++ b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/unitgroupconfig/UnitGroupMemberRecursionConsistencyHandler.kt @@ -1,6 +1,5 @@ package org.openbase.bco.registry.unit.core.consistency.unitgroupconfig -import org.openbase.bco.registry.lib.util.UnitConfigProcessor import org.openbase.jul.exception.CouldNotPerformException import org.openbase.jul.exception.InvalidStateException import org.openbase.jul.extension.protobuf.IdentifiableMessage @@ -8,9 +7,7 @@ import org.openbase.jul.extension.protobuf.container.ProtoBufMessageMap import org.openbase.jul.extension.type.processing.LabelProcessor import org.openbase.jul.storage.registry.AbstractProtoBufRegistryConsistencyHandler import org.openbase.jul.storage.registry.EntryModification -import org.openbase.jul.storage.registry.ProtoBufFileSynchronizedRegistry import org.openbase.jul.storage.registry.ProtoBufRegistry -import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig /* @@ -35,14 +32,14 @@ import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig * #L% */ /** @author [Tamino Huxohl](mailto:pleminoq@openbase.org) */ class UnitGroupMemberRecursionConsistencyHandler - : AbstractProtoBufRegistryConsistencyHandler() { + : AbstractProtoBufRegistryConsistencyHandler() { @Throws(CouldNotPerformException::class, EntryModification::class) override fun processData( id: String, - entry: IdentifiableMessage, - entryMap: ProtoBufMessageMap, - registry: ProtoBufRegistry + entry: IdentifiableMessage, + entryMap: ProtoBufMessageMap, + registry: ProtoBufRegistry, ) { val unitGroupUnitConfig = entry.message ?: return val memberIds = unitGroupUnitConfig.unitGroupConfig.memberIdList.toList() @@ -50,14 +47,16 @@ class UnitGroupMemberRecursionConsistencyHandler unitGroupUnitConfig .takeIf { memberIds.containsUnit(it, registry) } ?.let { - throw InvalidStateException("UnitGroup[${LabelProcessor.getBestMatch(unitGroupUnitConfig.label)}] " + - "refers itself as member!") + throw InvalidStateException( + "UnitGroup[${LabelProcessor.getBestMatch(unitGroupUnitConfig.label)}] " + + "refers itself as member!" + ) } } private fun List.containsUnit( unit: UnitConfig, - registry: ProtoBufRegistry + registry: ProtoBufRegistry, ): Boolean = this .filter { registry.contains(it) } .mapNotNull { registry.get(it).message } From d25aa014b51149a9477eb269871e77c3536614b3 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Thu, 16 Feb 2023 21:29:04 +0100 Subject: [PATCH 3/8] link against compatible jul version --- lib/jul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jul b/lib/jul index 2d6455eb70..6dbb9b62bc 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit 2d6455eb70b099e331140db1ddb37e6d62836b2e +Subproject commit 6dbb9b62bc58e3673abca89e297fb09cd9a7664f From 31b7dac44298d3dc545b0e2d4cb820f8ffad0931 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Thu, 16 Feb 2023 23:25:02 +0100 Subject: [PATCH 4/8] formatting --- .../bco/api/graphql/schema/UnitSchemaModule.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt index fa07311c9d..469f4044fe 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt @@ -42,7 +42,8 @@ import java.util.concurrent.TimeUnit * License along with this program. If not, see * . * #L% - */ class UnitSchemaModule : SchemaModule() { + */ +class UnitSchemaModule : SchemaModule() { // ===================================== Schema Modifications ====================================================== @SchemaModification(addField = "config", onType = UnitDataType.UnitData::class) @Throws( @@ -104,7 +105,7 @@ import java.util.concurrent.TimeUnit fun unit( @Arg("unitId") unitId: String, @Arg("data") data: UnitDataType.UnitData, - env: DataFetchingEnvironment + env: DataFetchingEnvironment, ): UnitDataType.UnitData { return try { setServiceStates( @@ -128,7 +129,7 @@ import java.util.concurrent.TimeUnit fun units( @Arg("filter") unitFilter: UnitFilterType.UnitFilter?, @Arg("data") data: UnitDataType.UnitData, - env: DataFetchingEnvironment + env: DataFetchingEnvironment, ): ImmutableList { return try { val dataList: MutableList = ArrayList() @@ -163,7 +164,7 @@ import java.util.concurrent.TimeUnit data: UnitDataType.UnitData, env: DataFetchingEnvironment, timeout: Long, - timeUnit: TimeUnit + timeUnit: TimeUnit, ): UnitDataType.UnitData { return setServiceStates(unitConfig.id, data, env, timeout, timeUnit) } @@ -174,7 +175,7 @@ import java.util.concurrent.TimeUnit data: UnitDataType.UnitData, env: DataFetchingEnvironment, timeout: Long, - timeUnit: TimeUnit + timeUnit: TimeUnit, ): UnitDataType.UnitData { val unit = Units.getUnit(unitId, timeout, timeUnit) val remoteActions: MutableList = ArrayList() From b94bc61eb6a34b1fe34c68ce0fc2f5db5d0ba102 Mon Sep 17 00:00:00 2001 From: Tamino Huxohl Date: Tue, 7 Mar 2023 20:02:17 +0100 Subject: [PATCH 5/8] implement caching of unit configs by type --- .../unit/core/UnitRegistryController.java | 35 +-- .../bco/registry/unit/lib/UnitRegistry.java | 246 ++++-------------- .../unit/remote/UnitRegistryRemote.java | 25 +- 3 files changed, 83 insertions(+), 223 deletions(-) diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java index 21ade6629d..5b3617b12c 100644 --- a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java +++ b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/UnitRegistryController.java @@ -46,7 +46,10 @@ import org.openbase.bco.registry.unit.core.consistency.sceneconfig.SceneServiceStateConsistencyHandler; import org.openbase.bco.registry.unit.core.consistency.sceneconfig.ServiceStateDescriptionHierarchyConsistencyHandler; import org.openbase.bco.registry.unit.core.consistency.unitgroupconfig.*; -import org.openbase.bco.registry.unit.core.consistency.userconfig.*; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserConfigLanguageConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserConfigUserNameConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserPermissionConsistencyHandler; +import org.openbase.bco.registry.unit.core.consistency.userconfig.UserUnitLabelConsistencyHandler; import org.openbase.bco.registry.unit.core.plugin.*; import org.openbase.bco.registry.unit.lib.UnitRegistry; import org.openbase.bco.registry.unit.lib.auth.AuthorizationWithTokenHelper; @@ -193,6 +196,22 @@ protected void postInit() throws InitializationException, InterruptedException { } } + @Override + public void activate() throws InterruptedException, CouldNotPerformException { + this.addDataObserver(clearUnitConfigsByTypeObserver); + CachedTemplateRegistryRemote.getRegistry().addDataObserver(clearUnitConfigsByTypeObserver); + + super.activate(); + } + + @Override + public void deactivate() throws InterruptedException, CouldNotPerformException { + this.removeDataObserver(clearUnitConfigsByTypeObserver); + CachedTemplateRegistryRemote.getRegistry().removeDataObserver(clearUnitConfigsByTypeObserver); + + super.deactivate(); + } + /** * {@inheritDoc} */ @@ -553,9 +572,7 @@ public UnitConfig getUnitConfigById(final String unitConfigId) throws NotAvailab * {@inheritDoc} * * @param unitAlias {@inheritDoc} - * * @return {@inheritDoc} - * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -577,9 +594,7 @@ public UnitConfig getUnitConfigByAlias(final String unitAlias) throws NotAvailab * * @param unitAlias {@inheritDoc} * @param unitType {@inheritDoc} - * * @return {@inheritDoc} - * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -659,9 +674,7 @@ public Future removeUnitConfigAuthenticated(final Authentica * {@inheritDoc} * * @param filterDisabledUnits {@inheritDoc} - * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} * @throws NotAvailableException {@inheritDoc} */ @@ -685,7 +698,6 @@ public List getUnitConfigsFiltered(boolean filterDisabledUnits) thro * {@inheritDoc} * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -697,7 +709,6 @@ public List getDalUnitConfigs() throws CouldNotPerformException { * {@inheritDoc} * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -748,9 +759,7 @@ public Boolean isUnitGroupConfigRegistryConsistent() { * {@inheritDoc} * * @param serviceType - * * @return - * * @throws CouldNotPerformException */ @Override @@ -771,9 +780,7 @@ public List getServiceConfigsByServiceType(final ServiceType serv * * @param unitType * @param serviceTypes - * * @return - * * @throws CouldNotPerformException */ @Override @@ -1041,7 +1048,6 @@ protected UnitRegistryData filterDataForUser(final UnitRegistryData.Builder data * {@inheritDoc} * * @param authorizationToken {@inheritDoc} - * * @return {@inheritDoc} */ @Override @@ -1060,7 +1066,6 @@ public Future requestAuthorizationToken(final AuthorizationToken authori * {@inheritDoc} * * @param authenticatedValue {@inheritDoc} - * * @return {@inheritDoc} */ @Override diff --git a/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/UnitRegistry.java b/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/UnitRegistry.java index ee529ecc67..d46caff53b 100644 --- a/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/UnitRegistry.java +++ b/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/UnitRegistry.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -31,7 +31,6 @@ import org.openbase.bco.registry.lib.provider.UnitConfigCollectionProvider; import org.openbase.bco.registry.lib.util.UnitConfigProcessor; import org.openbase.bco.registry.template.remote.CachedTemplateRegistryRemote; -import org.openbase.bco.registry.unit.lib.filter.UnitConfigFilter; import org.openbase.bco.registry.unit.lib.filter.UnitConfigFilterImpl; import org.openbase.bco.registry.unit.lib.provider.UnitTransformationProviderRegistry; import org.openbase.jul.annotation.RPCMethod; @@ -43,11 +42,12 @@ import org.openbase.jul.iface.Shutdownable; import org.openbase.jul.pattern.Filter; import org.openbase.jul.pattern.ListFilter; +import org.openbase.jul.pattern.Observer; import org.openbase.jul.pattern.provider.DataProvider; import org.openbase.jul.schedule.GlobalCachedExecutorService; +import org.openbase.jul.schedule.SyncObject; import org.openbase.jul.storage.registry.RegistryService; import org.openbase.type.communication.ScopeType.Scope; -import org.openbase.type.domotic.action.ActionDescriptionType.ActionDescription; import org.openbase.type.domotic.authentication.AuthenticatedValueType.AuthenticatedValue; import org.openbase.type.domotic.authentication.AuthenticationTokenType.AuthenticationToken; import org.openbase.type.domotic.authentication.AuthorizationTokenType.AuthorizationToken; @@ -55,7 +55,6 @@ import org.openbase.type.domotic.service.ServiceConfigType; import org.openbase.type.domotic.service.ServiceConfigType.ServiceConfig; import org.openbase.type.domotic.service.ServiceDescriptionType.ServiceDescription; -import org.openbase.type.domotic.service.ServiceStateDescriptionType.ServiceStateDescription; import org.openbase.type.domotic.service.ServiceTemplateType.ServiceTemplate.ServicePattern; import org.openbase.type.domotic.service.ServiceTemplateType.ServiceTemplate.ServiceType; import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; @@ -72,7 +71,6 @@ import javax.media.j3d.Transform3D; import javax.vecmath.Point3d; -import java.rmi.ServerError; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -107,13 +105,28 @@ public interface UnitRegistry extends DataProvider, UnitTransf * The default radius used for the unit by coordinate lookup is set to 1 metre. */ double DEFAULT_RADIUS = 1d; + /** + * Cache of unit configs by type. + */ + Map> unitConfigsByType = new HashMap<>(); + /** + * Lock to synchronize access to unit configs by type cache. + */ + SyncObject unitConfigsByTypeMapLock = new SyncObject("unitConfigsByTypeMapLock"); + /** + * Observer which may be registered to clear the unit configs by type cache on changes. + */ + Observer clearUnitConfigsByTypeObserver = (source, data) -> { + synchronized (unitConfigsByTypeMapLock) { + unitConfigsByType.clear(); + } + }; /** * This method registers the given unit config in the registry. * Future get canceled if the entry already exists or results in an inconsistent registry * * @param unitConfig the unit config to register. - * * @return the registered unit config with all applied consistency changes. */ @RPCMethod @@ -126,7 +139,6 @@ public interface UnitRegistry extends DataProvider, UnitTransf * Method updates the given unit config. * * @param unitConfig the updated unit config. - * * @return the updated unit config with all applied consistency changes. */ @RPCMethod @@ -139,7 +151,6 @@ public interface UnitRegistry extends DataProvider, UnitTransf * Method removes the given unit config out of the global registry. * * @param unitConfig the unit config to remove. - * * @return The removed unit config. */ @RPCMethod @@ -154,7 +165,6 @@ public interface UnitRegistry extends DataProvider, UnitTransf * comparison. * * @param unitConfig the unit config used for the identification. - * * @return true if the unit exists or false if the entry does not exists or the registry is not available. */ @RPCMethod @@ -223,15 +233,12 @@ default String getUnitScopeByAlias(final String alias) throws CouldNotPerformExc * Hint: If you want to address more than one unit with an alias than create a unit group of such units and define an alias for those group. * * @param unitAlias the alias to identify the unit. - * * @return the unit config referred by the alias. - * * @throws NotAvailableException is thrown if no unit is matching the given alias. */ @RPCMethod UnitConfig getUnitConfigByAlias(final String unitAlias) throws NotAvailableException; - /** * Method returns the unit matching the given alias. An alias is a unique identifier of units. *

@@ -239,9 +246,7 @@ default String getUnitScopeByAlias(final String alias) throws CouldNotPerformExc * * @param unitAlias the alias to identify the unit. * @param unitType the type to validate the resulting unit. - * * @return the unit config referred by the alias. - * * @throws NotAvailableException is thrown if no unit is matching the given alias. * @deprecated please use getUnitConfigByAliasAndUnitType(...) instead. */ @@ -257,9 +262,7 @@ default UnitConfig getUnitConfigByAlias(String unitAlias, final UnitType unitTyp * * @param unitAlias the alias to identify the unit. * @param unitType the type to validate the resulting unit. - * * @return the unit config referred by the alias. - * * @throws NotAvailableException is thrown if no unit is matching the given alias. */ UnitConfig getUnitConfigByAliasAndUnitType(String unitAlias, final UnitType unitType) throws NotAvailableException; @@ -271,9 +274,7 @@ default UnitConfig getUnitConfigByAlias(String unitAlias, final UnitType unitTyp * Note: PLEASE DO NOT USE THIS METHOD TO REQUEST DEVICES FOR THE CONTROLLING PURPOSE BECAUSE LABELS ARE NOT A STABLE IDENTIFIER! USE ID OR ALIAS INSTEAD! * * @param unitConfigLabel the label to identify a set of units. - * * @return a list of the requested unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLabel(final String unitConfigLabel) throws CouldNotPerformException { @@ -296,26 +297,12 @@ default List getUnitConfigsByLabelAndUnitType(final String unitConfi return unitConfigs; } - /** - * Method returns a list of all globally registered units of the given {@code type}. - *

- * Note: The type {@code UnitType.UNKNOWN} is used as wildcard and will return a list of all registered units. - * - * @param unitType the unit type to filter. - * - * @return a list of unit configurations. - * - * @throws CouldNotPerformException is thrown in case something goes wrong during the request. - */ - /** * Method returns all registered unit configs. It allows to filter unit configs. * * @param includeDisabledUnits if true all unit configs that are disabled will be included as well. - * @param unitFilter if set, only units that match the filter will be returned. - * + * @param unitFilter if set, only units that match the filter will be returned. * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final boolean includeDisabledUnits, final UnitFilter unitFilter) throws CouldNotPerformException { @@ -326,9 +313,7 @@ default List getUnitConfigs(final boolean includeDisabledUnits, fina * Method returns all registered unit configs. It allows to filter unit configs. * * @param unitFilter if set, only units that match the filter will be returned. - * * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final UnitFilter unitFilter) throws CouldNotPerformException { @@ -339,10 +324,8 @@ default List getUnitConfigs(final UnitFilter unitFilter) throws Coul * Method returns all registered unit configs. It allows to filter unit configs. * * @param includeDisabledUnits if true all unit configs that are disabled will be included as well. - * @param unitFilter if set, only units that match the filter will be returned. - * + * @param unitFilter if set, only units that match the filter will be returned. * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final boolean includeDisabledUnits, final Filter unitFilter) throws CouldNotPerformException { @@ -354,9 +337,7 @@ default List getUnitConfigs(final boolean includeDisabledUnits, fina * Method returns all registered unit configs. It allows to filter unit configs. * * @param unitFilter if set, only units that match the filter will be returned. - * * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final Filter unitFilter) throws CouldNotPerformException { @@ -367,10 +348,8 @@ default List getUnitConfigs(final Filter unitFilter) thr * Method returns all registered unit configs. It allows to filter unit configs. * * @param includeDisabledUnits if true all unit configs that are disabled will be included as well. - * @param unitFilter if set, only units that match the filter will be returned. - * + * @param unitFilter if set, only units that match the filter will be returned. * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final boolean includeDisabledUnits, final ListFilter unitFilter) throws CouldNotPerformException { @@ -381,9 +360,7 @@ default List getUnitConfigs(final boolean includeDisabledUnits, fina * Method returns all registered unit configs. It allows to filter unit configs. * * @param unitFilter if set, only units that match the filter will be returned. - * * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final ListFilter unitFilter) throws CouldNotPerformException { @@ -394,9 +371,7 @@ default List getUnitConfigs(final ListFilter unitFilter) * Method returns all registered unit configs. It allows to filter unit configs. * * @param includeDisabledUnits if true all unit configs that are disabled will be included as well. - * * @return the unit config collection as queried. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigs(final boolean includeDisabledUnits) throws CouldNotPerformException { @@ -409,9 +384,7 @@ default List getUnitConfigs(final boolean includeDisabledUnits) thro * Note: The type {@code UnitType.UNKNOWN} is used as wildcard and will return a list of all registered units. * * @param unitType the unit type to filter. - * * @return a list of unit configurations. - * * @throws CouldNotPerformException is thrown in case something goes wrong during the request. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByUnitType(...) instead. */ @@ -426,20 +399,25 @@ default List getUnitConfigs(final UnitType unitType) throws CouldNot * Note: The type {@code UnitType.UNKNOWN} is used as wildcard and will return a list of all registered units. * * @param unitType the unit type to filter. - * * @return a list of unit configurations. - * * @throws CouldNotPerformException is thrown in case something goes wrong during the request. */ default List getUnitConfigsByUnitType(final UnitType unitType) throws CouldNotPerformException { validateData(); - List unitConfigs = new ArrayList<>(); - for (UnitConfig unitConfig : getUnitConfigs()) { - if (unitType == UnitType.UNKNOWN || unitConfig.getUnitType() == unitType || CachedTemplateRegistryRemote.getRegistry().getSubUnitTypes(unitType).contains(unitConfig.getUnitType())) { - unitConfigs.add(unitConfig); + + synchronized (unitConfigsByTypeMapLock) { + if (!unitConfigsByType.containsKey(unitType)) { + List unitConfigs = new ArrayList<>(); + for (UnitConfig unitConfig : getUnitConfigs()) { + if (unitType == UnitType.UNKNOWN || unitConfig.getUnitType() == unitType || CachedTemplateRegistryRemote.getRegistry().getSubUnitTypes(unitType).contains(unitConfig.getUnitType())) { + unitConfigs.add(unitConfig); + } + } + unitConfigsByType.put(unitType, unitConfigs); } + + return unitConfigsByType.get(unitType); } - return unitConfigs; } /** @@ -449,9 +427,7 @@ default List getUnitConfigsByUnitType(final UnitType unitType) throw * * @param unitType the unit type to filter. * @param filterDisabledUnits if flag is true only enabled units are returned, otherwise all unit are returned. - * * @return a list of unit configurations. - * * @throws CouldNotPerformException is thrown in case something goes wrong during the request. */ default List getUnitConfigsByUnitTypeFiltered(final UnitType unitType, final boolean filterDisabledUnits) throws CouldNotPerformException { @@ -471,7 +447,6 @@ default List getUnitConfigsByUnitTypeFiltered(final UnitType unitTyp * Base units are units of the following types: LOCATION, CONNECTION, SCENE, AGENT, APP, DEVICE, USER, AUTHORIZATION_GROUP, UNIT_GROUP * * @return a list of dal units. - * * @throws CouldNotPerformException is thrown in case something goes wrong during the request. */ List getDalUnitConfigs() throws CouldNotPerformException; @@ -481,14 +456,12 @@ default List getUnitConfigsByUnitTypeFiltered(final UnitType unitTyp * Base units are units of the following types: LOCATION, CONNECTION, SCENE, AGENT, APP, DEVICE, USER, AUTHORIZATION_GROUP, UNIT_GROUP * * @return a list of base units. - * * @throws CouldNotPerformException is thrown in case something goes wrong during the request. */ List getBaseUnitConfigs() throws CouldNotPerformException; /** * @return a list containing all service configs of all units. - * * @throws CouldNotPerformException is thrown if the config list could not be generated. */ default List getServiceConfigs() throws CouldNotPerformException { @@ -503,9 +476,7 @@ default List getServiceConfigs() throws CouldNotPerformException * Method returns all service configs of all units filtered by the given {@code serviceType}. * * @param serviceType the service type to filter. - * * @return a list of service configs matching the given {@code serviceType}. - * * @throws CouldNotPerformException is thrown if the config list could not be generated. * @deprecated please use getServiceConfigsByServiceType(...) instead. */ @@ -518,9 +489,7 @@ default List getServiceConfigs(final ServiceType serviceType) thr * Method returns all service configs of all units filtered by the given {@code serviceType}. * * @param serviceType the service type to filter. - * * @return a list of service configs matching the given {@code serviceType}. - * * @throws CouldNotPerformException is thrown if the config list could not be generated. */ default List getServiceConfigsByServiceType(final ServiceType serviceType) throws CouldNotPerformException { @@ -552,9 +521,7 @@ default List getServiceConfigsByServiceType(final ServiceType ser * * @param unitType the unit type to filter. * @param serviceType the service type to filter. - * * @return a list of unit types matching the given unit and service type. - * * @throws CouldNotPerformException is thrown if the list could not be generated. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByUnitTypeAndServiceType(...) instead. */ @@ -568,9 +535,7 @@ default List getUnitConfigsByUnitTypeAndServiceTypes(final UnitType * * @param unitType the unit type to filter. * @param serviceType the service type to filter. - * * @return a list of unit types matching the given unit and service type. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitConfigsByUnitTypeAndServiceType(final UnitType unitType, final ServiceType serviceType) throws CouldNotPerformException { @@ -596,9 +561,7 @@ default List getUnitConfigsByUnitTypeAndServiceType(final UnitType u * * @param unitType the unit type to filter. * @param serviceTypes a list of service types to filter. - * * @return a list of unit types matching the given unit and service type. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitConfigsByUnitTypeAndServiceTypes(final UnitType unitType, final List serviceTypes) throws CouldNotPerformException { @@ -625,9 +588,7 @@ default List getUnitConfigsByUnitTypeAndServiceTypes(final UnitType * Method returns a list of all unit group configs where the given unit config is a member of the group. * * @param unitConfig the unit config used to identify the member unit. - * * @return a list of unit group configs. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitGroupUnitConfigsByUnitConfig(final UnitConfig unitConfig) throws CouldNotPerformException { @@ -638,9 +599,7 @@ default List getUnitGroupUnitConfigsByUnitConfig(final UnitConfig un * Method returns a list of all unit group configs where the given unit is a member of the group. * * @param unitId the unit id defining the member unit. - * * @return a list of unit group configs. - * * @throws CouldNotPerformException is thrown if the list could not be generated. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitGroupUnitConfigsByUnitId(...) instead. */ @@ -654,9 +613,7 @@ default List getUnitGroupUnitConfigsByUnitConfig(final String unitId * Method returns a list of all unit group configs where the given unit is a member of the group. * * @param unitId the unit id defining the member unit. - * * @return a list of unit group configs. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitGroupUnitConfigsByUnitId(final String unitId) throws CouldNotPerformException { @@ -673,9 +630,7 @@ default List getUnitGroupUnitConfigsByUnitId(final String unitId) th * Method returns a list of all unit group configs which are providing at least one member of the given {@code unitType}. * * @param unitType the unit type to filter the groups. - * * @return a list of unit group configs. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitGroupUnitConfigsByUnitType(final UnitType unitType) throws CouldNotPerformException { @@ -692,9 +647,7 @@ default List getUnitGroupUnitConfigsByUnitType(final UnitType unitTy * Method returns all unit configs filtered by the given {@code serviceType}. * * @param serviceType the service types to filter. - * * @return a list of unit types matching the given service types. - * * @throws CouldNotPerformException is thrown if the list could not be generated. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitGroupUnitConfigsByServiceType(...) instead. */ @@ -707,9 +660,7 @@ default List getUnitGroupUnitConfigsByServiceTypes(final ServiceType * Method returns all unit configs filtered by the given {@code serviceType}. * * @param serviceType the service types to filter. - * * @return a list of unit types matching the given service types. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitGroupUnitConfigsByServiceType(final ServiceType serviceType) throws CouldNotPerformException { @@ -729,9 +680,7 @@ default List getUnitGroupUnitConfigsByServiceType(final ServiceType * Method returns all unit configs filtered by the given {@code serviceTypes}. * * @param serviceTypes a list of service types to filter. - * * @return a list of unit types matching the given service types. - * * @throws CouldNotPerformException is thrown if the list could not be generated. */ default List getUnitGroupUnitConfigsByServiceTypes(final List serviceTypes) throws CouldNotPerformException { @@ -755,9 +704,7 @@ default List getUnitGroupUnitConfigsByServiceTypes(final List getUnitConfigsByUnitGroupConfig(final UnitConfig unitGroupUnitConfig) throws CouldNotPerformException { @@ -775,9 +722,7 @@ default List getUnitConfigsByUnitGroupConfig(final UnitConfig unitGr * given scope. * * @param scope the scope of the unit used as identifier. - * * @return the unit config matching the given scope. - * * @throws CouldNotPerformException */ @RPCMethod @@ -792,7 +737,6 @@ default UnitConfig getUnitConfigByScope(final Scope scope) throws CouldNotPerfor /** * @param unitConfig - * * @throws VerificationFailedException * @deprecated since 2.0 and will be removed in 3.0: please use UnitConfigProcessor.verifyUnitConfig(unitConfig, UnitType.UNIT_GROUP) instead. */ @@ -1094,7 +1038,6 @@ default Future> getUnitConfigsByCoordinate(final Vec3DDouble co * * @param coordinate the center of the sphere. * @param radius the radius of the sphere. - * * @return all units included in the sphere. */ default Future> getUnitConfigsByCoordinateAndRadius(final Vec3DDouble coordinate, final double radius) { @@ -1109,7 +1052,6 @@ default Future> getUnitConfigsByCoordinateAndRadius(final Vec3D * @param coordinate the center of the sphere. * @param radius the radius of the sphere. * @param unitType filter lets only pass units of this declared type. - * * @return all units placed in the sphere. */ default Future> getUnitConfigsByCoordinateAndRadiusAndUnitType(final Vec3DDouble coordinate, final double radius, final UnitType unitType) { @@ -1136,9 +1078,7 @@ default Future> getUnitConfigsByCoordinateAndRadiusAndUnitType( * If multiple users happen to have the same user name, the first one is returned. * * @param userName - * * @return User ID - * * @throws CouldNotPerformException * @throws NotAvailableException If no user with the given user name could be found. */ @@ -1159,9 +1099,7 @@ default String getUserUnitIdByUserName(final String userName) throws CouldNotPer * Method returns all location unit configs which are of the given location type. * * @param locationType the type of the location. - * * @return a list of the requested unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getLocationUnitConfigsByLocationType(...) instead. */ @@ -1174,9 +1112,7 @@ default List getLocationUnitConfigsByType(final LocationType locatio * Method returns all location unit configs which are of the given location type. * * @param locationType the type of the location. - * * @return a list of the requested unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getLocationUnitConfigsByLocationType(final LocationType locationType) throws CouldNotPerformException { @@ -1193,7 +1129,6 @@ default List getLocationUnitConfigsByLocationType(final LocationType * Call to {@link #getLocationUnitConfigsByCoordinateAndLocationType(Vec3DDouble, LocationType)} with location type unknown. * * @param coordinate the coordinate for which it is checked if it is inside a location. - * * @return a list of the requested unit configs sorted by location type. */ default Future> getLocationUnitConfigsByCoordinate(final Vec3DDouble coordinate) { @@ -1208,7 +1143,6 @@ default Future> getLocationUnitConfigsByCoordinate(final Vec3DD * * @param coordinate the coordinate for which it is checked if it is inside a location * @param locationType the type of locations checked, unknown means all locations - * * @return a future of a list of the requested unit configs sorted by location type */ default Future> getLocationUnitConfigsByCoordinateAndLocationType(final Vec3DDouble coordinate, final LocationType locationType) { @@ -1295,9 +1229,7 @@ default Future> getLocationUnitConfigsByCoordinateAndLocationTy * Method returns all unit configurations which are direct or recursive related to the given location id. * * @param locationId the id of the location which provides the units. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationId(...) instead. */ @@ -1310,9 +1242,7 @@ default List getUnitConfigsByLocationIdAndUnitType(final String loca * Method returns all unit configurations which are direct or recursive related to the given location id. * * @param locationId the id of the location which provides the units. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationId(final String locationId) throws CouldNotPerformException { @@ -1325,9 +1255,7 @@ default List getUnitConfigsByLocationId(final String locationId) thr * * @param locationId the id of the location which provides the units. * @param recursive defines if recursive related unit should be included as well. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationIdRecursive(...) instead. */ @@ -1342,9 +1270,7 @@ default List getUnitConfigsByLocation(final String locationId, final * * @param locationId the id of the location which provides the units. * @param recursive defines if recursive related unit should be included as well. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdRecursive(final String locationId, final boolean recursive) throws CouldNotPerformException { @@ -1365,9 +1291,7 @@ default List getUnitConfigsByLocationIdRecursive(final String locati * * @param unitType the unit type after which unit configs are filtered. * @param locationId the location inside which unit configs are resolved. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationIdAndUnitType(...) instead. */ @@ -1383,9 +1307,7 @@ default List getUnitConfigsByLocation(final UnitType unitType, final * * @param unitType the unit type after which unit configs are filtered. * @param locationId the location inside which unit configs are resolved. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdAndUnitType(final String locationId, final UnitType unitType) throws CouldNotPerformException { @@ -1402,9 +1324,7 @@ default List getUnitConfigsByLocationIdAndUnitType(final String loca * @param unitType the unit type after which unit configs are filtered. * @param locationId the location inside which unit configs are resolved. * @param recursive defines if recursive related unit should be included as well. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdAndUnitTypeRecursive(final String locationId, final UnitType unitType, final boolean recursive) throws CouldNotPerformException { @@ -1419,9 +1339,7 @@ default List getUnitConfigsByLocationIdAndUnitTypeRecursive(final St * @param unitType the unit type after which unit configs are filtered. * @param locationId the location inside which unit configs are resolved. * @param recursive defines if recursive related unit should be included as well. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdAndUnitTypeInclusiveSuperTypeRecursive(final String locationId, final UnitType unitType, final boolean inclusiveSuperType, final boolean recursive) throws CouldNotPerformException { @@ -1469,9 +1387,7 @@ default List getUnitConfigsByLocationIdAndUnitTypeInclusiveSuperType * * @param type service type filter. * @param locationConfigId related location. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationIdAndServiceType(...) instead. @@ -1487,9 +1403,7 @@ default List getUnitConfigsByLocation(final ServiceType type, final * * @param locationConfigId related location. * @param serviceType service type filter. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException */ @@ -1500,7 +1414,7 @@ default List getUnitConfigsByLocationIdAndServiceType(final String l for (String unitConfigId : getUnitConfigById(locationConfigId).getLocationConfig().getUnitIdList()) { try { unitConfig = getUnitConfigById(unitConfigId); - if(isServiceAvailable(serviceType, unitConfig)) { + if (isServiceAvailable(serviceType, unitConfig)) { unitConfigList.add(unitConfig); } } catch (CouldNotPerformException ex) { @@ -1513,7 +1427,7 @@ default List getUnitConfigsByLocationIdAndServiceType(final String l default boolean isServiceAvailable(final ServiceType serviceType, final UnitConfig unitConfig) { for (ServiceConfig serviceConfig : unitConfig.getServiceConfigList()) { - if(serviceConfig.getServiceDescription().getPattern() != ServicePattern.PROVIDER) { + if (serviceConfig.getServiceDescription().getPattern() != ServicePattern.PROVIDER) { continue; } @@ -1528,33 +1442,33 @@ default boolean isServiceAvailable(final ServiceType serviceType, final UnitConf switch (unitConfig.getUnitType()) { case LOCATION: - if(unitConfig - .getLocationConfig() - .getUnitIdList() - .stream() - .anyMatch(it -> { - try { - if(it.equals(unitConfig.getId())) { - new FatalImplementationErrorException("Location "+LabelProcessor.getBestMatch(unitConfig.getLabel())+" refers it self as child unit!", this); + if (unitConfig + .getLocationConfig() + .getUnitIdList() + .stream() + .anyMatch(it -> { + try { + if (it.equals(unitConfig.getId())) { + new FatalImplementationErrorException("Location " + LabelProcessor.getBestMatch(unitConfig.getLabel()) + " refers it self as child unit!", this); + return false; + } + return isServiceAvailable(serviceType, getUnitConfigById(it)); + } catch (NotAvailableException exception) { return false; } - return isServiceAvailable(serviceType, getUnitConfigById(it)); - } catch (NotAvailableException exception) { - return false; - } - })) { + })) { return true; } break; case UNIT_GROUP: - if(unitConfig + if (unitConfig .getUnitGroupConfig() .getMemberIdList() .stream() .anyMatch(it -> { try { - if(it.equals(unitConfig.getId())) { - new FatalImplementationErrorException("Unit Group "+LabelProcessor.getBestMatch(unitConfig.getLabel())+" refers it self as member unit!", this); + if (it.equals(unitConfig.getId())) { + new FatalImplementationErrorException("Unit Group " + LabelProcessor.getBestMatch(unitConfig.getLabel()) + " refers it self as member unit!", this); return false; } return isServiceAvailable(serviceType, getUnitConfigById(it)); @@ -1567,7 +1481,7 @@ default boolean isServiceAvailable(final ServiceType serviceType, final UnitConf break; default: new FatalImplementationErrorException( - "Unit["+LabelProcessor.getBestMatch(unitConfig.getLabel(), "?")+"] provides an aggregated service thats not allowed for units of type: "+ unitConfig.getUnitType().name() + "Unit[" + LabelProcessor.getBestMatch(unitConfig.getLabel(), "?") + "] provides an aggregated service thats not allowed for units of type: " + unitConfig.getUnitType().name() , this ); } @@ -1580,9 +1494,7 @@ default boolean isServiceAvailable(final ServiceType serviceType, final UnitConf * related to the given location id. * * @param locationId - * * @return the list of service configurations. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException is thrown if the given location config id * is unknown. @@ -1598,9 +1510,7 @@ default List getServiceConfigsByLocation(final String locationId) * related to the given location id. * * @param locationId - * * @return the list of service configurations. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException is thrown if the given location config id * is unknown. @@ -1619,9 +1529,7 @@ default List getServiceConfigsByLocationId(final String locationI * related to the given location alias. * * @param locationAlias the alias to identify the location. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationAlias(final String locationAlias) throws CouldNotPerformException { @@ -1639,9 +1547,7 @@ default List getUnitConfigsByLocationAlias(final String locationAlia * * @param unitLabel the label tested * @param locationId the id of the location from which units are returned - * * @return a list of unit configs containing the given label withing the given location - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationIdAndUnitLabel(...) instead. */ @@ -1657,9 +1563,7 @@ default List getUnitConfigsByLabelAndLocation(final String unitLabel * * @param unitLabel the label tested * @param locationId the id of the location from which units are returned - * * @return a list of unit configs containing the given label withing the given location - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdAndUnitLabel(final String locationId, final String unitLabel) throws CouldNotPerformException { @@ -1676,9 +1580,7 @@ default List getUnitConfigsByLocationIdAndUnitLabel(final String loc * @param unitLabel the label tested * @param locationId the id of the location from which units are returned * @param recursive flag determining if the whole location tree should be considered - * * @return a list of unit configs containing the given label withing the given location - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationIdAndUnitLabelRecursive(...) instead. */ @@ -1697,9 +1599,7 @@ default List getUnitConfigsByLabelAndLocation(final String unitLabel * @param locationId the id of the location from which units are returned * @param unitLabel the label tested * @param recursive flag determining if the whole location tree should be considered - * * @return a list of unit configs containing the given label withing the given location - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByLocationIdAndUnitLabelRecursive(final String locationId, final String unitLabel, final boolean recursive) throws CouldNotPerformException { @@ -1719,9 +1619,7 @@ default List getUnitConfigsByLocationIdAndUnitLabelRecursive(final S * * @param unitType * @param locationAlias - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByLocationAliasAndUnitType(...) instead. @@ -1738,9 +1636,7 @@ default List getUnitConfigsByLocationAlias(final UnitType unitType, * * @param unitType * @param locationAlias - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException */ @@ -1756,9 +1652,7 @@ default List getUnitConfigsByLocationAliasAndUnitType(final String l * Method generates a list of service types supported by the given location. * * @param locationId the location to filter the types. - * * @return a list of supported service types. - * * @throws NotAvailableException is thrown in case the list could not be computed. * @deprecated since 2.0 and will be removed in 3.0: please use getServiceTypesByLocationId(...) instead. */ @@ -1771,9 +1665,7 @@ default Set getServiceTypesByLocation(final String locationId) thro * Method generates a list of service types supported by the given location. * * @param locationId the location to filter the types. - * * @return a list of supported service types. - * * @throws NotAvailableException is thrown in case the list could not be computed. */ default Set getServiceTypesByLocationId(final String locationId) throws CouldNotPerformException { @@ -1791,9 +1683,7 @@ default Set getServiceTypesByLocationId(final String locationId) th * connection id. * * @param connectionConfigId - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByConnectionId(...) instead. */ @@ -1807,9 +1697,7 @@ default List getUnitConfigsByConnection(final String connectionConfi * connection id. * * @param connectionConfigId - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getUnitConfigsByConnectionId(final String connectionConfigId) throws CouldNotPerformException { @@ -1826,9 +1714,7 @@ default List getUnitConfigsByConnectionId(final String connectionCon * * @param type * @param connectionConfigId - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByConnectionIdAndUnitType(...) instead. @@ -1844,9 +1730,7 @@ default List getUnitConfigsByConnection(final UnitType type, final S * * @param connectionConfigId * @param unitType - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException */ @@ -1873,9 +1757,7 @@ default List getUnitConfigsByConnectionIdAndUnitType(final String co * * @param type service type filter. * @param connectionConfigId related connection. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException * @deprecated since 2.0 and will be removed in 3.0: please use getUnitConfigsByConnectionIdAndServiceType(...) instead. @@ -1891,9 +1773,7 @@ default List getUnitConfigsByConnection(final ServiceType type, fina * * @param connectionConfigId related connection. * @param serviceType service type filter. - * * @return A collection of unit configs. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException */ @@ -1922,9 +1802,7 @@ default List getUnitConfigsByConnectionIdAndServiceType(final String * connection id. * * @param connectionConfigId - * * @return the list of service configurations. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException is thrown if the given connection config id * is unknown. @@ -1940,9 +1818,7 @@ default List getServiceConfigsByConnection(final String connectio * connection id. * * @param connectionConfigId - * * @return the list of service configurations. - * * @throws CouldNotPerformException is thrown if the request fails. * @throws NotAvailableException is thrown if the given connection config id * is unknown. @@ -1960,9 +1836,7 @@ default List getServiceConfigsByConnectionId(final String connect * does not belong to a tile, the could not perform exception is thrown. * * @param locationId the id of the location which neighbors you want to get - * * @return all neighbor tiles - * * @throws CouldNotPerformException is thrown if the request fails. * @deprecated since 2.0 and will be removed in 3.0: please use getNeighborLocationsByLocationId(...) instead. */ @@ -1976,9 +1850,7 @@ default List getNeighborLocations(final String locationId) throws Co * does not belong to a tile, the could not perform exception is thrown. * * @param locationId the id of the location which neighbors you want to get - * * @return all neighbor tiles - * * @throws CouldNotPerformException is thrown if the request fails. */ default List getNeighborLocationsByLocationId(final String locationId) throws CouldNotPerformException { @@ -2007,9 +1879,7 @@ default List getNeighborLocationsByLocationId(final String locationI * Method returns all agent unit configs which are based on the given agent class. * * @param agentClass the agent class to identify the units. - * * @return a list of matching agent configs. - * * @throws CouldNotPerformException is thrown in case the list could not be generated. */ default List getAgentUnitConfigsByAgentClass(final AgentClass agentClass) throws CouldNotPerformException { @@ -2020,9 +1890,7 @@ default List getAgentUnitConfigsByAgentClass(final AgentClass agentC * Method returns all agent unit configs which are based on the given agent class. * * @param agentClassId the if of the agent class to identify the units. - * * @return a list of matching agent configs. - * * @throws CouldNotPerformException is thrown in case the list could not be generated. */ default List getAgentUnitConfigsByAgentClassId(final String agentClassId) throws CouldNotPerformException { @@ -2043,9 +1911,7 @@ default List getAgentUnitConfigsByAgentClassId(final String agentCla * Method returns all app unit configs which are based on the given app class. * * @param appClass the app class to identify the units. - * * @return a list of matching app configs. - * * @throws CouldNotPerformException is thrown in case the list could not be generated. */ default List getAppUnitConfigsByAppClass(final AppClass appClass) throws CouldNotPerformException, InterruptedException { @@ -2056,9 +1922,7 @@ default List getAppUnitConfigsByAppClass(final AppClass appClass) th * Method returns all app unit configs which are based on the given app class. * * @param appClassId the if of the app class to identify the units. - * * @return a list of matching app configs. - * * @throws CouldNotPerformException is thrown in case the list could not be generated. */ default List getAppUnitConfigsByAppClassId(final String appClassId) throws CouldNotPerformException, InterruptedException { @@ -2086,7 +1950,6 @@ default List getAppUnitConfigsByAppClassId(final String appClassId) * Else the token cannot be verified and encrypted which means everybody listening could use it. * * @param authorizationToken the authorizationToken which is verified an encrypted - * * @return a future of a task that verifies and encrypts the token */ Future requestAuthorizationToken(final AuthorizationToken authorizationToken); @@ -2102,7 +1965,6 @@ default List getAppUnitConfigsByAppClassId(final String appClassId) * * @param authenticatedValue The authenticated value for the request containing a valid ticket and an authorizationToken encrypted * with the session key. - * * @return The future of a task that creates an authenticated value containing an updated ticket and the token encoded via Base64 * and encrypted with the session key. */ diff --git a/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java index 0e919ce69e..773ba83456 100644 --- a/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java +++ b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -34,8 +34,10 @@ import org.openbase.jps.core.JPService; import org.openbase.jps.preset.JPReadOnly; import org.openbase.jul.communication.controller.RPCUtils; -import org.openbase.jul.exception.*; +import org.openbase.jul.exception.CouldNotPerformException; import org.openbase.jul.exception.InstantiationException; +import org.openbase.jul.exception.InvalidStateException; +import org.openbase.jul.exception.NotAvailableException; import org.openbase.jul.extension.protobuf.IdentifiableMessage; import org.openbase.jul.extension.type.processing.LabelProcessor; import org.openbase.jul.extension.type.util.TransactionSynchronizationFuture; @@ -153,12 +155,16 @@ public void waitForData() throws CouldNotPerformException, InterruptedException @Override public void activate() throws InterruptedException, CouldNotPerformException { unitConfigRemoteRegistry.addDataObserver(aliasMapUpdateObserver); + unitConfigRemoteRegistry.addDataObserver(clearUnitConfigsByTypeObserver); + CachedUnitRegistryRemote.getRegistry().addDataObserver(clearUnitConfigsByTypeObserver); super.activate(); } @Override public void deactivate() throws InterruptedException, CouldNotPerformException { unitConfigRemoteRegistry.removeDataObserver(aliasMapUpdateObserver); + unitConfigRemoteRegistry.removeDataObserver(clearUnitConfigsByTypeObserver); + CachedUnitRegistryRemote.getRegistry().removeDataObserver(clearUnitConfigsByTypeObserver); super.deactivate(); } @@ -334,7 +340,6 @@ public RemoteRegistry getBaseUnitConfigR * {@inheritDoc} * * @param unitConfig {@inheritDoc} - * * @return {@inheritDoc} */ @Override @@ -351,9 +356,7 @@ public Future registerUnitConfigAuthenticated(AuthenticatedV * {@inheritDoc} * * @param unitConfigId {@inheritDoc} - * * @return {@inheritDoc} - * * @throws org.openbase.jul.exception.NotAvailableException {@inheritDoc} */ @Override @@ -370,9 +373,7 @@ public UnitConfig getUnitConfigById(final String unitConfigId) throws NotAvailab * {@inheritDoc} * * @param unitAlias {@inheritDoc} - * * @return {@inheritDoc} - * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -394,9 +395,7 @@ public UnitConfig getUnitConfigByAlias(final String unitAlias) throws NotAvailab * * @param unitAlias {@inheritDoc} * @param unitType {@inheritDoc} - * * @return {@inheritDoc} - * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -457,9 +456,7 @@ public Future removeUnitConfigAuthenticated(final Authentica * {@inheritDoc} * * @param filterDisabledUnits {@inheritDoc} - * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} * @throws NotAvailableException {@inheritDoc} */ @@ -481,7 +478,6 @@ public List getUnitConfigsFiltered(boolean filterDisabledUnits) thro * {@inheritDoc} * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -502,7 +498,6 @@ public List getDalUnitConfigs() throws CouldNotPerformException { * {@inheritDoc} * * @return {@inheritDoc} - * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -878,7 +873,6 @@ public Boolean isGatewayUnitRegistryConsistent() { * {@inheritDoc} * * @param authorizationToken {@inheritDoc} - * * @return {@inheritDoc} */ @Override @@ -895,7 +889,6 @@ public Future requestAuthorizationToken(final AuthorizationToken authori * {@inheritDoc} * * @param authenticatedValue {@inheritDoc} - * * @return {@inheritDoc} */ @Override From 97e01602c61e2370fb87a00e54b42f7eeb8aaa1a Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 4 Apr 2023 19:54:42 +0200 Subject: [PATCH 6/8] update jul to latest version --- lib/jul | 2 +- lib/type | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jul b/lib/jul index a09736b115..c042bac636 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit a09736b11596defa3bdba7fa1efd55630f5e7f43 +Subproject commit c042bac636025c440dfb5eaf0cdbd0f3b7f767a2 diff --git a/lib/type b/lib/type index 9f2ef6ac30..99e866c784 160000 --- a/lib/type +++ b/lib/type @@ -1 +1 @@ -Subproject commit 9f2ef6ac300fa26bd2c353dea96fdd6c3696fc48 +Subproject commit 99e866c78450e7ae410f2bc594a239b5b53ab970 From 38209fada5bf51973721ffe1490da6da8a7de875 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Thu, 13 Apr 2023 19:47:18 +0200 Subject: [PATCH 7/8] convert SchemaModificationsAdd back to java since its rejointer does not work with kotlin reflections. --- .../graphql/schema/RegistrySchemaModule.kt | 2 +- ...ionsAdd.kt => SchemaModificationsAdd.java} | 0 .../BcoGraphQlApiApplicationTests.java | 35 ----------- versions.properties | 61 +++++++++++++++++++ 4 files changed, 62 insertions(+), 36 deletions(-) rename module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/{SchemaModificationsAdd.kt => SchemaModificationsAdd.java} (100%) delete mode 100644 module/api/graphql/src/test/java/org/openbase/bco/api/graphql/BcoGraphQlApiApplicationTests.java diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt index b402e48190..4b745918e0 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt @@ -258,7 +258,7 @@ import java.util.concurrent.* ServerError.Companion.BCO_TIMEOUT_TIME_UNIT ).getUnitConfigById(unitId).toBuilder() val context = env.getContext() - val oldLabel = getBestMatch(context.languageCode, builder.label) + val oldLabel = getBestMatch(context.languageCode!!, builder.label) replace(builder.labelBuilder, oldLabel, label) Registries.getUnitRegistry() .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].label diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.java similarity index 100% rename from module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.kt rename to module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/SchemaModificationsAdd.java diff --git a/module/api/graphql/src/test/java/org/openbase/bco/api/graphql/BcoGraphQlApiApplicationTests.java b/module/api/graphql/src/test/java/org/openbase/bco/api/graphql/BcoGraphQlApiApplicationTests.java deleted file mode 100644 index 35c3563dd7..0000000000 --- a/module/api/graphql/src/test/java/org/openbase/bco/api/graphql/BcoGraphQlApiApplicationTests.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.openbase.bco.api.graphql; - -/*- - * #%L - * BCO GraphQL API - * %% - * Copyright (C) 2020 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -//import org.junit.jupiter.api.Test; -//import org.springframework.boot.test.context.SpringBootTest; -// -//@SpringBootTest -class BcoGraphQlApiApplicationTests { - -// @Test -// void contextLoads() { -// } - -} diff --git a/versions.properties b/versions.properties index ba9a8b711c..eb13ab729b 100644 --- a/versions.properties +++ b/versions.properties @@ -6,11 +6,32 @@ #### #### suppress inspection "SpellCheckingInspection" for whole file #### suppress inspection "UnusedProperty" for whole file + +version.com.adarshr..gradle-test-logger-plugin=3.2.0 + version.com.graphql-java-kickstart..graphql-spring-boot-starter=14.0.0 + version.io.quarkus..quarkus-junit4-mock=2.9.1.Final + ## unused version.junit.jupiter=5.9.2 + +version.kotest=5.5.5 +## # available=5.6.0.1123-SNAPSHOT +## # available=5.6.0.1125-SNAPSHOT +## # available=5.6.0.1126-SNAPSHOT +## # available=5.6.0.1127-SNAPSHOT +## # available=5.6.0.1128-SNAPSHOT +## # available=5.6.0.1129-SNAPSHOT +## # available=5.6.0.1131-SNAPSHOT + +version.kotlinx.coroutines=1.6.4 +## # available=1.7.0-Beta + +version.mockk=1.13.4 + version.org.jmdns..jmdns=3.5.7 + version.org.glassfish.jersey.security..oauth2-client=2.31 ## # available=2.32 ## # available=2.33 @@ -23,6 +44,7 @@ version.org.glassfish.jersey.security..oauth2-client=2.31 ## # available=3.0.1 ## # available=3.0.2 ## # available=3.0.3 + version.org.glassfish.jersey.media..jersey-media-sse=2.31 ## # available=2.32 ## # available=2.33 @@ -35,6 +57,7 @@ version.org.glassfish.jersey.media..jersey-media-sse=2.31 ## # available=3.0.1 ## # available=3.0.2 ## # available=3.0.3 + version.org.glassfish.jersey.inject..jersey-hk2=2.31 ## # available=2.32 ## # available=2.33 @@ -47,6 +70,7 @@ version.org.glassfish.jersey.inject..jersey-hk2=2.31 ## # available=3.0.1 ## # available=3.0.2 ## # available=3.0.3 + version.org.glassfish.jersey.core..jersey-client=2.31 ## # available=2.32 ## # available=2.33 @@ -59,25 +83,34 @@ version.org.glassfish.jersey.core..jersey-client=2.31 ## # available=3.0.1 ## # available=3.0.2 ## # available=3.0.3 + version.org.apache.commons..commons-math3=3.6.1 + version.net.javacrumbs.future-converter..future-converter-java8-guava=1.2.0 + version.io.socket..socket.io-client=1.0.0 ## # available=1.0.1 ## # available=2.0.0 ## # available=2.0.1 + version.io.reactivex.rxjava2..rxjava=2.2.21 + version.commons-collections..commons-collections=3.2.2 ## # available=20030418.083655 ## # available=20031027.000000 ## # available=20040102.233541 ## # available=20040616 + ## unused version.com.influxdb..influxdb-client-java=[5.0,5.1-alpha) + version.com.google.inject.extensions..guice-multibindings=4.2.3 + version.com.google.inject..guice=5.0.1 ## # available=5.0.2-SNAPSHOT ## # available=5.1.0 ## # available=5.1.1-SNAPSHOT + version.com.google.guava..guava=28.0-jre ## # available=28.1-android ## # available=28.1-jre @@ -95,74 +128,102 @@ version.com.google.guava..guava=28.0-jre ## # available=31.0-jre ## # available=31.0.1-android ## # available=31.0.1-jre + +version.org.openbase..jul.communication.mqtt.test=3.3-SNAPSHOT + version.org.openbase..jul.transformation=3.3-SNAPSHOT + version.org.testcontainers..junit-jupiter=1.17.2 + version.org.testcontainers..testcontainers=1.17.1 + version.org.springframework.boot..spring-boot-starter-webflux=2.6.3 + version.org.springframework.boot..spring-boot-starter-jetty=2.6.3 + version.org.springframework.boot..spring-boot-starter-websocket=2.6.3 + version.org.springframework..spring-webmvc=5.3.15 + version.org.openhab.core.bundles..org.openhab.core.io.rest.core=3.1.0 ## # available=3.1.1 ## # available=3.2.0 + plugin.org.springframework.boot=2.6.2 ## # available=2.6.3 + plugin.io.spring.dependency-management=1.0.11.RELEASE + version.kotlin=1.7.0 + version.org.openbase..jul.communication.controller=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.communication.mqtt=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.exception=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.extension.protobuf=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.extension.type.processing=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.extension.type.storage=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.extension.type.transform=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.extension.type.util=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.pattern.launch=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.pattern.trigger=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.processing=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.storage=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.visual.javafx=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.org.openbase..jul.visual.swing=3.3-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 + version.rxjava2.rxjava=2.2.21 From 7b56b41fbe0e8635913d77d7cae9a19066ff3091 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Wed, 19 Apr 2023 21:18:45 +0200 Subject: [PATCH 8/8] auth check implemented for all gql mutations. --- .../context/AbstractBCOGraphQLContext.kt | 7 +- .../bco/api/graphql/context/GQLExtensions.kt | 5 + .../graphql/schema/RegistrySchemaModule.kt | 533 +++++++++--------- .../api/graphql/schema/UnitSchemaModule.kt | 158 +++--- .../unit/remote/UnitRegistryRemote.java | 13 + .../UnitRegistryRemoteAuthExtensions.kt | 39 ++ 6 files changed, 388 insertions(+), 367 deletions(-) create mode 100644 module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLExtensions.kt create mode 100644 module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemoteAuthExtensions.kt diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt index ab942b6249..5dc614b01f 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/AbstractBCOGraphQLContext.kt @@ -3,6 +3,7 @@ package org.openbase.bco.api.graphql.context import graphql.kickstart.execution.context.DefaultGraphQLContext import org.dataloader.DataLoaderRegistry import org.openbase.jul.exception.NotAvailableException +import org.openbase.type.domotic.authentication.AuthTokenType /*- * #%L @@ -24,13 +25,17 @@ import org.openbase.jul.exception.NotAvailableException * License along with this program. If not, see * . * #L% - */ abstract class AbstractBCOGraphQLContext( + */ +abstract class AbstractBCOGraphQLContext( dataLoaderRegistry: DataLoaderRegistry?, ) : DefaultGraphQLContext(dataLoaderRegistry) { @get:Throws(NotAvailableException::class) abstract val token: String? abstract val languageCode: String? + val auth: AuthTokenType.AuthToken? + get() = AuthTokenType.AuthToken.newBuilder().setAuthenticationToken(token).build() + companion object { const val DATA_LOADER_UNITS = "units" } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLExtensions.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLExtensions.kt new file mode 100644 index 0000000000..0f5fd9cd35 --- /dev/null +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/context/GQLExtensions.kt @@ -0,0 +1,5 @@ +package org.openbase.bco.api.graphql.context + +import graphql.schema.DataFetchingEnvironment + +val DataFetchingEnvironment.context get() = (this.getContext() as AbstractBCOGraphQLContext) diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt index 4b745918e0..c3f96ee52a 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/RegistrySchemaModule.kt @@ -3,23 +3,24 @@ package org.openbase.bco.api.graphql.schema import com.google.api.graphql.rejoiner.* import com.google.common.collect.ImmutableList import graphql.schema.DataFetchingEnvironment -import org.openbase.bco.api.graphql.context.AbstractBCOGraphQLContext +import org.openbase.bco.api.graphql.context.context import org.openbase.bco.api.graphql.error.ArgumentError import org.openbase.bco.api.graphql.error.BCOGraphQLError import org.openbase.bco.api.graphql.error.GenericError import org.openbase.bco.api.graphql.error.ServerError import org.openbase.bco.authentication.lib.SessionManager -import org.openbase.bco.authentication.lib.future.AuthenticatedValueFuture import org.openbase.bco.authentication.lib.iface.BCOSession import org.openbase.bco.registry.remote.Registries import org.openbase.bco.registry.remote.session.BCOSessionImpl +import org.openbase.bco.registry.unit.remote.registerUnitConfigAuthenticated +import org.openbase.bco.registry.unit.remote.removeUnitConfigAuthenticated +import org.openbase.bco.registry.unit.remote.updateUnitConfigAuthenticated import org.openbase.jul.exception.CouldNotPerformException import org.openbase.jul.extension.protobuf.ProtoBufBuilderProcessor.mergeFromWithoutRepeatedFields import org.openbase.jul.extension.type.processing.LabelProcessor.getBestMatch import org.openbase.jul.extension.type.processing.LabelProcessor.replace import org.openbase.type.configuration.EntryType import org.openbase.type.configuration.MetaConfigType -import org.openbase.type.domotic.authentication.AuthTokenType import org.openbase.type.domotic.unit.UnitConfigType import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig import org.openbase.type.domotic.unit.UnitFilterType @@ -79,23 +80,21 @@ import java.util.concurrent.* */ @Query("login") @Throws(BCOGraphQLError::class) - fun login(@Arg("username") username: String?, @Arg("password") passwordHash: String?): String { - return try { - val session: BCOSession = BCOSessionImpl() - session.loginUserViaUsername(username, Base64.getDecoder().decode(passwordHash), false) - session.generateAuthToken( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).authenticationToken - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun login(@Arg("username") username: String?, @Arg("password") passwordHash: String?): String = try { + val session: BCOSession = BCOSessionImpl() + session.loginUserViaUsername(username, Base64.getDecoder().decode(passwordHash), false) + session.generateAuthToken( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).authenticationToken + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Query("changePassword") @@ -104,52 +103,47 @@ import java.util.concurrent.* @Arg("username") username: String?, @Arg("oldPassword") oldPassword: String?, @Arg("newPassword") newPassword: String?, - ): String { + ): String = try { + val userId = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUserUnitIdByUserName(username) + val sessionManager = SessionManager() try { - val userId = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUserUnitIdByUserName(username) - val sessionManager = SessionManager() - try { - sessionManager.loginUser(userId, oldPassword, false) - } catch (ex: CouldNotPerformException) { - throw ArgumentError(ex) - } - sessionManager.changePassword( - userId, - oldPassword, - newPassword - )[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] - } catch (ex: RuntimeException) { - throw GenericError(ex) + sessionManager.loginUser(userId, oldPassword, false) } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) + throw ArgumentError(ex) } - return "läuft" - } + sessionManager.changePassword( + userId, + oldPassword, + newPassword + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) + }.let { "" } @Query("unitConfig") @Throws(BCOGraphQLError::class) - fun getUnitConfigById(@Arg("id") id: String?, env: DataFetchingEnvironment?): UnitConfigType.UnitConfig { - return try { - Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(id) - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } + fun getUnitConfigById(@Arg("id") id: String?): UnitConfigType.UnitConfig = try { + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(id) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } @Query("unitConfigs") @@ -157,92 +151,97 @@ import java.util.concurrent.* fun queryGetUnitConfigs( @Arg("filter") unitFilter: UnitFilterType.UnitFilter?, @Arg("includeDisabledUnits") includeDisabledUnits: Boolean?, - ): ImmutableList { - return getUnitConfigs(unitFilter, includeDisabledUnits) - } + ): ImmutableList = getUnitConfigs(unitFilter, includeDisabledUnits) - // ===================================== Mutations ================================================================= @Query("gatewayClasses") @Throws(CouldNotPerformException::class, InterruptedException::class) - fun gatewayClasses(): ImmutableList { - return ImmutableList.copyOf(Registries.getClassRegistry(true).gatewayClasses) - } + fun gatewayClasses(): ImmutableList = + ImmutableList.copyOf(Registries.getClassRegistry(true).gatewayClasses) @Mutation("updateUnitConfig") @Throws(BCOGraphQLError::class) - fun updateUnitConfig(@Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig): UnitConfigType.UnitConfig { - return try { - val unitConfigBuilder = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - .getUnitConfigById(unitConfig.id) - .toBuilder() - unitConfigBuilder.mergeFromWithoutRepeatedFields(unitConfig) - Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - .updateUnitConfig(unitConfigBuilder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun updateUnitConfig( + @Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig, + env: DataFetchingEnvironment, + ): UnitConfigType.UnitConfig = try { + val unitConfigBuilder = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + .getUnitConfigById(unitConfig.id) + .toBuilder() + unitConfigBuilder.mergeFromWithoutRepeatedFields(unitConfig) + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).updateUnitConfigAuthenticated( + unitConfigBuilder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("removeUnitConfig") @Throws(BCOGraphQLError::class) - fun removeUnitConfig(@Arg("unitId") unitId: String?): UnitConfigType.UnitConfig { - return try { - val unitConfig = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(unitId) - Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - .removeUnitConfig(unitConfig)[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun removeUnitConfig( + @Arg("unitId") unitId: String?, + env: DataFetchingEnvironment, + ): UnitConfigType.UnitConfig = try { + val unitConfig = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId) + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).removeUnitConfigAuthenticated( + unitConfig, + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("registerUnitConfig") @Throws(BCOGraphQLError::class) - fun registerUnitConfig(@Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig?): UnitConfigType.UnitConfig { - return try { - Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - .registerUnitConfig(unitConfig)[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT] - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun registerUnitConfig( + @Arg("unitConfig") unitConfig: UnitConfigType.UnitConfig?, + env: DataFetchingEnvironment, + ): UnitConfigType.UnitConfig = try { + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).registerUnitConfigAuthenticated( + unitConfig, + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT] + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("updateLabel") @@ -251,28 +250,27 @@ import java.util.concurrent.* @Arg("unitId") unitId: String?, @Arg("label") label: String?, env: DataFetchingEnvironment, - ): LabelType.Label { - return try { - val builder = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(unitId).toBuilder() - val context = env.getContext() - val oldLabel = getBestMatch(context.languageCode!!, builder.label) - replace(builder.labelBuilder, oldLabel, label) - Registries.getUnitRegistry() - .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].label - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + ): LabelType.Label = try { + val builder = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + val oldLabel = getBestMatch(env.context.languageCode!!, builder.label) + replace(builder.labelBuilder, oldLabel, label) + Registries.getUnitRegistry().updateUnitConfigAuthenticated( + builder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT].label + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("updateLocation") @@ -280,148 +278,141 @@ import java.util.concurrent.* fun updateLocation( @Arg("unitId") unitId: String?, @Arg("locationId") locationId: String?, - ): PlacementConfigType.PlacementConfig { - return try { - val builder = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(unitId).toBuilder() - builder.placementConfigBuilder.locationId = locationId - Registries.getUnitRegistry() - .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + env: DataFetchingEnvironment, + ): PlacementConfigType.PlacementConfig = try { + val builder = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + builder.placementConfigBuilder.locationId = locationId + Registries.getUnitRegistry().updateUnitConfigAuthenticated( + builder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT].placementConfig + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("updateFloorPlan") @Throws(BCOGraphQLError::class) - fun updateFloorPlan(@Arg("locationId") locationId: String?, @Arg("shape") shape: ShapeType.Shape): ShapeType.Shape { - return try { - val unitConfigBuilder = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(locationId).toBuilder() - unitConfigBuilder.placementConfigBuilder.shapeBuilder.clearFloor().addAllFloor(shape.floorList) - Registries.getUnitRegistry() - .updateUnitConfig(unitConfigBuilder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig.shape - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun updateFloorPlan( + @Arg("locationId") locationId: String?, + @Arg("shape") shape: ShapeType.Shape, + env: DataFetchingEnvironment, + ): ShapeType.Shape = try { + val unitConfigBuilder = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(locationId).toBuilder() + unitConfigBuilder.placementConfigBuilder.shapeBuilder.clearFloor().addAllFloor(shape.floorList) + Registries.getUnitRegistry().updateUnitConfigAuthenticated( + unitConfigBuilder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT].placementConfig.shape + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } @Mutation("updatePose") @Throws(BCOGraphQLError::class) - fun updatePose(@Arg("unitId") unitId: String?, @Arg("pose") pose: PoseType.Pose?): PoseType.Pose { - return try { - val builder = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(unitId).toBuilder() - builder.placementConfigBuilder.clearPose().pose = pose - Registries.getUnitRegistry() - .updateUnitConfig(builder.build())[ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT].placementConfig.pose - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) - } catch (ex: TimeoutException) { - throw GenericError(ex) - } + fun updatePose( + @Arg("unitId") unitId: String?, + @Arg("pose") pose: PoseType.Pose?, + env: DataFetchingEnvironment, + ): PoseType.Pose = try { + val builder = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(unitId).toBuilder() + builder.placementConfigBuilder.clearPose().pose = pose + Registries.getUnitRegistry().updateUnitConfigAuthenticated( + builder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT].placementConfig.pose + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) + } catch (ex: TimeoutException) { + throw GenericError(ex) } - // ===================================== Service Methods =========================================================== + @Mutation("updateMetaConfig") @Throws(BCOGraphQLError::class) fun updateMetaConfig( @Arg("unitId") unitId: String?, @Arg("entry") entry: EntryType.Entry, env: DataFetchingEnvironment, - ): MetaConfigType.MetaConfig { - return try { - val unitRegistry = Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - val unitConfigBuilder = unitRegistry.getUnitConfigById(unitId).toBuilder() - val metaConfigBuilder = unitConfigBuilder.metaConfigBuilder - for (i in 0 until metaConfigBuilder.entryCount) { - if (metaConfigBuilder.getEntry(i).key == entry.key) { - metaConfigBuilder.removeEntry(i) - break - } - } - if (!entry.value.isEmpty()) { - metaConfigBuilder.addEntry(entry) + ): MetaConfigType.MetaConfig = try { + val unitRegistry = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + val unitConfigBuilder = unitRegistry.getUnitConfigById(unitId).toBuilder() + val metaConfigBuilder = unitConfigBuilder.metaConfigBuilder + for (i in 0 until metaConfigBuilder.entryCount) { + if (metaConfigBuilder.getEntry(i).key == entry.key) { + metaConfigBuilder.removeEntry(i) + break } - val sessionManager = SessionManager.getInstance() - val authToken = AuthTokenType.AuthToken.newBuilder() - .setAuthenticationToken((env.getContext() as AbstractBCOGraphQLContext).token).build() - val request = sessionManager.initializeRequest(unitConfigBuilder.build(), authToken) - val future = unitRegistry.updateUnitConfigAuthenticated(request) - val authFuture: AuthenticatedValueFuture = AuthenticatedValueFuture( - future, - UnitConfig::class.java, - request.ticketAuthenticatorWrapper, - sessionManager - ) - authFuture.get()!!.metaConfig - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } catch (ex: ExecutionException) { - throw GenericError(ex) } + if (!entry.value.isEmpty()) { + metaConfigBuilder.addEntry(entry) + } + + unitRegistry.updateUnitConfigAuthenticated( + unitConfigBuilder.build(), + env.context.auth + )[ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT]!!.metaConfig + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) + } catch (ex: ExecutionException) { + throw GenericError(ex) } companion object { - // ===================================== Queries =================================================================== @Throws(BCOGraphQLError::class) fun getUnitConfigs( unitFilter: UnitFilterType.UnitFilter?, includeDisabledUnits: Boolean?, - ): ImmutableList { - var includeDisabledUnits: Boolean? = includeDisabledUnits - return try { - if (includeDisabledUnits == null) { - includeDisabledUnits = true - } - ImmutableList.copyOf( - Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigs(includeDisabledUnits, unitFilter) - ) - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } + ): ImmutableList = try { + ImmutableList.copyOf( + Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigs(includeDisabledUnits ?: true, unitFilter) + ) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } } } diff --git a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt index 469f4044fe..abe50510bb 100644 --- a/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt +++ b/module/api/graphql/src/main/java/org/openbase/bco/api/graphql/schema/UnitSchemaModule.kt @@ -46,57 +46,49 @@ import java.util.concurrent.TimeUnit class UnitSchemaModule : SchemaModule() { // ===================================== Schema Modifications ====================================================== @SchemaModification(addField = "config", onType = UnitDataType.UnitData::class) - @Throws( - CouldNotPerformException::class, InterruptedException::class - ) - fun addConfigToData(data: UnitDataType.UnitData): UnitConfigType.UnitConfig { - return Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigById(data.id) - } + @Throws(CouldNotPerformException::class, InterruptedException::class) + fun addConfigToData(data: UnitDataType.UnitData): UnitConfigType.UnitConfig = Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigById(data.id) // ===================================== Queries =================================================================== @Query("unit") @Throws(BCOGraphQLError::class) - fun unit(@Arg("unitId") id: String?): UnitDataType.UnitData { - return try { - val unit = - Units.getUnit(id, ServerError.Companion.BCO_TIMEOUT_SHORT, ServerError.Companion.BCO_TIMEOUT_TIME_UNIT) - merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } + fun unit(@Arg("unitId") id: String?): UnitDataType.UnitData = try { + Units + .getUnit(id, ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT) + .let { unit -> merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData } + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } @Query("units") @Throws(BCOGraphQLError::class) - fun units(@Arg("filter") unitFilter: UnitFilterType.UnitFilter?): ImmutableList { - return try { - val dataList: MutableList = ArrayList() - for (unitConfig in Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigs(unitFilter)) { - val unit = Units.getUnit( - unitConfig, - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - dataList.add(merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData) - } - ImmutableList.copyOf(dataList) - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) + fun units(@Arg("filter") unitFilter: UnitFilterType.UnitFilter?): ImmutableList = try { + val dataList: MutableList = ArrayList() + for (unitConfig in Registries.getUnitRegistry( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ).getUnitConfigs(unitFilter)) { + val unit = Units.getUnit( + unitConfig, + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + dataList.add(merge(UnitDataType.UnitData.newBuilder(), unit.data).build() as UnitDataType.UnitData) } + ImmutableList.copyOf(dataList) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } // ===================================== Queries =================================================================== @@ -106,22 +98,14 @@ class UnitSchemaModule : SchemaModule() { @Arg("unitId") unitId: String, @Arg("data") data: UnitDataType.UnitData, env: DataFetchingEnvironment, - ): UnitDataType.UnitData { - return try { - setServiceStates( - unitId, - data, - env, - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } + ): UnitDataType.UnitData = try { + setServiceStates(unitId, data, env) + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } @Mutation("units") @@ -130,31 +114,17 @@ class UnitSchemaModule : SchemaModule() { @Arg("filter") unitFilter: UnitFilterType.UnitFilter?, @Arg("data") data: UnitDataType.UnitData, env: DataFetchingEnvironment, - ): ImmutableList { - return try { - val dataList: MutableList = ArrayList() - for (unitConfig in Registries.getUnitRegistry( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ).getUnitConfigs(unitFilter)) { - dataList.add( - setServiceStates( - unitConfig, - data, - env, - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - ) - } - ImmutableList.copyOf(dataList) - } catch (ex: RuntimeException) { - throw GenericError(ex) - } catch (ex: CouldNotPerformException) { - throw GenericError(ex) - } catch (ex: InterruptedException) { - throw GenericError(ex) - } + ): ImmutableList = try { + Registries.getUnitRegistry(ServerError.BCO_TIMEOUT_SHORT, ServerError.BCO_TIMEOUT_TIME_UNIT) + .getUnitConfigs(unitFilter) + .map { config -> setServiceStates(config, data, env) } + .let { ImmutableList.copyOf(it) } + } catch (ex: RuntimeException) { + throw GenericError(ex) + } catch (ex: CouldNotPerformException) { + throw GenericError(ex) + } catch (ex: InterruptedException) { + throw GenericError(ex) } // ===================================== Service Methods =========================================================== @@ -163,8 +133,8 @@ class UnitSchemaModule : SchemaModule() { unitConfig: UnitConfigType.UnitConfig, data: UnitDataType.UnitData, env: DataFetchingEnvironment, - timeout: Long, - timeUnit: TimeUnit, + timeout: Long = ServerError.BCO_TIMEOUT_SHORT, + timeUnit: TimeUnit = ServerError.BCO_TIMEOUT_TIME_UNIT, ): UnitDataType.UnitData { return setServiceStates(unitConfig.id, data, env, timeout, timeUnit) } @@ -174,8 +144,8 @@ class UnitSchemaModule : SchemaModule() { unitId: String, data: UnitDataType.UnitData, env: DataFetchingEnvironment, - timeout: Long, - timeUnit: TimeUnit, + timeout: Long = ServerError.BCO_TIMEOUT_SHORT, + timeUnit: TimeUnit = ServerError.BCO_TIMEOUT_TIME_UNIT, ): UnitDataType.UnitData { val unit = Units.getUnit(unitId, timeout, timeUnit) val remoteActions: MutableList = ArrayList() @@ -200,14 +170,12 @@ class UnitSchemaModule : SchemaModule() { } val unitDataBuilder = UnitDataType.UnitData.newBuilder() // TODO: blocked by https://github.com/openbase/bco.dal/issues/170 - if (!remoteActions.isEmpty()) { - for (remoteAction in remoteActions) { - remoteAction.waitForRegistration( - ServerError.Companion.BCO_TIMEOUT_SHORT, - ServerError.Companion.BCO_TIMEOUT_TIME_UNIT - ) - unitDataBuilder.addTriggeredAction(remoteAction.actionDescription) - } + for (remoteAction in remoteActions) { + remoteAction.waitForRegistration( + ServerError.BCO_TIMEOUT_SHORT, + ServerError.BCO_TIMEOUT_TIME_UNIT + ) + unitDataBuilder.addTriggeredAction(remoteAction.actionDescription) } merge(unitDataBuilder, unit.data) return unitDataBuilder.build() diff --git a/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java index 773ba83456..50f3395e9b 100644 --- a/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java +++ b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemote.java @@ -340,6 +340,7 @@ public RemoteRegistry getBaseUnitConfigR * {@inheritDoc} * * @param unitConfig {@inheritDoc} + * * @return {@inheritDoc} */ @Override @@ -356,7 +357,9 @@ public Future registerUnitConfigAuthenticated(AuthenticatedV * {@inheritDoc} * * @param unitConfigId {@inheritDoc} + * * @return {@inheritDoc} + * * @throws org.openbase.jul.exception.NotAvailableException {@inheritDoc} */ @Override @@ -373,7 +376,9 @@ public UnitConfig getUnitConfigById(final String unitConfigId) throws NotAvailab * {@inheritDoc} * * @param unitAlias {@inheritDoc} + * * @return {@inheritDoc} + * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -395,7 +400,9 @@ public UnitConfig getUnitConfigByAlias(final String unitAlias) throws NotAvailab * * @param unitAlias {@inheritDoc} * @param unitType {@inheritDoc} + * * @return {@inheritDoc} + * * @throws NotAvailableException {@inheritDoc} */ @Override @@ -456,7 +463,9 @@ public Future removeUnitConfigAuthenticated(final Authentica * {@inheritDoc} * * @param filterDisabledUnits {@inheritDoc} + * * @return {@inheritDoc} + * * @throws CouldNotPerformException {@inheritDoc} * @throws NotAvailableException {@inheritDoc} */ @@ -478,6 +487,7 @@ public List getUnitConfigsFiltered(boolean filterDisabledUnits) thro * {@inheritDoc} * * @return {@inheritDoc} + * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -498,6 +508,7 @@ public List getDalUnitConfigs() throws CouldNotPerformException { * {@inheritDoc} * * @return {@inheritDoc} + * * @throws CouldNotPerformException {@inheritDoc} */ @Override @@ -873,6 +884,7 @@ public Boolean isGatewayUnitRegistryConsistent() { * {@inheritDoc} * * @param authorizationToken {@inheritDoc} + * * @return {@inheritDoc} */ @Override @@ -889,6 +901,7 @@ public Future requestAuthorizationToken(final AuthorizationToken authori * {@inheritDoc} * * @param authenticatedValue {@inheritDoc} + * * @return {@inheritDoc} */ @Override diff --git a/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemoteAuthExtensions.kt b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemoteAuthExtensions.kt new file mode 100644 index 0000000000..3c1f9c93da --- /dev/null +++ b/module/registry/unit-registry/remote/src/main/java/org/openbase/bco/registry/unit/remote/UnitRegistryRemoteAuthExtensions.kt @@ -0,0 +1,39 @@ +package org.openbase.bco.registry.unit.remote + +import org.openbase.bco.authentication.lib.SessionManager +import org.openbase.bco.authentication.lib.future.AuthenticatedValueFuture +import org.openbase.type.domotic.authentication.AuthTokenType +import org.openbase.type.domotic.authentication.AuthenticatedValueType +import org.openbase.type.domotic.unit.UnitConfigType +import java.io.Serializable +import java.util.concurrent.Future + +fun UnitRegistryRemote.updateUnitConfigAuthenticated( + unitConfig: UnitConfigType.UnitConfig?, + auth: AuthTokenType.AuthToken?, +): Future = authRequest(unitConfig, ::updateUnitConfigAuthenticated, auth) + +fun UnitRegistryRemote.removeUnitConfigAuthenticated( + unitConfig: UnitConfigType.UnitConfig?, + auth: AuthTokenType.AuthToken?, +): Future = authRequest(unitConfig, ::removeUnitConfigAuthenticated, auth) + +fun UnitRegistryRemote.registerUnitConfigAuthenticated( + unitConfig: UnitConfigType.UnitConfig?, + auth: AuthTokenType.AuthToken?, +): Future = authRequest(unitConfig, ::registerUnitConfigAuthenticated, auth) + +inline fun UnitRegistryRemote.authRequest( + value: T?, + origin: (AuthenticatedValueType.AuthenticatedValue) -> Future, + auth: AuthTokenType.AuthToken?, +): Future = with(SessionManager.getInstance()) { + initializeRequest(value, auth).let { value -> + AuthenticatedValueFuture( + origin(value), + T::class.java, + value.ticketAuthenticatorWrapper, + this + ) + } +}