Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe

Commits:

20 changed files:

Changes:

  • core/services/local/src/main/java/fr/ird/observe/services/local/ObserveServiceContextLocal.java
    ... ... @@ -53,6 +53,11 @@ public final class ObserveServiceContextLocal extends ObserveServicesProviderImp
    53 53
         private ObserveTopiaApplicationContext topiaApplicationContext;
    
    54 54
         private DecoratorService decoratorService;
    
    55 55
     
    
    56
    +    /**
    
    57
    +     * If any error was found, will stop any commit then closing transaction.
    
    58
    +     */
    
    59
    +    private Throwable error;
    
    60
    +
    
    56 61
         ObserveServiceContextLocal(ObserveServiceInitializer serviceInitializer, ObserveServiceFactory serviceFactory) {
    
    57 62
             super(serviceFactory, () -> serviceInitializer);
    
    58 63
         }
    
    ... ... @@ -143,6 +148,17 @@ public final class ObserveServiceContextLocal extends ObserveServicesProviderImp
    143 148
             return persistenceContext;
    
    144 149
         }
    
    145 150
     
    
    151
    +    public Throwable getError() {
    
    152
    +        return error;
    
    153
    +    }
    
    154
    +
    
    155
    +    public void setError(Throwable error, String methodName) {
    
    156
    +        this.error = Objects.requireNonNull(error);
    
    157
    +        if (log.isInfoEnabled()) {
    
    158
    +            log.error(String.format("Could not invoke for %s", methodName), error);
    
    159
    +        }
    
    160
    +    }
    
    161
    +
    
    146 162
         public void checkCredentials(String methodName, Permission methodeCredentials) {
    
    147 163
             if (methodeCredentials != null && serviceInitializer().withConnection()) {
    
    148 164
                 ObserveDataSourceConnection dataSourceConnection = serviceInitializer().getConnection();
    
    ... ... @@ -164,7 +180,11 @@ public final class ObserveServiceContextLocal extends ObserveServicesProviderImp
    164 180
         }
    
    165 181
     
    
    166 182
         private void commit(ObserveTopiaPersistenceContext persistenceContext) {
    
    167
    -        log.debug(String.format("Commit persistenceContext for %s", methodName));
    
    168
    -        persistenceContext.commit();
    
    183
    +        if (error == null) {
    
    184
    +            log.debug(String.format("Commit persistenceContext for %s", methodName));
    
    185
    +            persistenceContext.commit();
    
    186
    +        } else {
    
    187
    +            log.warn(String.format("Skip commit persistenceContext for %s, due to error on call...", methodName));
    
    188
    +        }
    
    169 189
         }
    
    170 190
     }

  • core/services/local/src/main/java/fr/ird/observe/services/local/service/ObserveServiceLocal.java
    ... ... @@ -334,8 +334,6 @@ public abstract class ObserveServiceLocal implements ObserveService, ServiceCont
    334 334
     
    
    335 335
         @Override
    
    336 336
         public final ServiceValidationContext createServiceValidationContext(ValidationRequestConfigurationSupport configuration, ValidationRequest request) {
    
    337
    -//        ObserveServicesProviderImpl servicesProvider = new ObserveServicesProviderImpl(serviceContext.serviceFactory(), serviceContext::serviceInitializer);
    
    338
    -//        ServiceValidationContext validationContext = new ServiceValidationContext((ValidationRequestConfiguration) configuration, getDecoratorService(), new ProjectSelectModel(), servicesProvider);
    
    339 337
             ServiceValidationContext validationContext = new ServiceValidationContext((ValidationRequestConfiguration) configuration, getDecoratorService(), new Project(), serviceContext);
    
    340 338
             validationContext.init();
    
    341 339
             return validationContext;
    
    ... ... @@ -353,12 +351,28 @@ public abstract class ObserveServiceLocal implements ObserveService, ServiceCont
    353 351
             return serviceContext.initWriteTransaction(methodName, methodeCredentials);
    
    354 352
         }
    
    355 353
     
    
    356
    -    protected final void closeTransaction(boolean doClose) {
    
    354
    +    protected final void recordError(Exception e, String methodName) {
    
    355
    +        serviceContext.setError(e, methodName);
    
    356
    +    }
    
    357
    +
    
    358
    +    protected final void closeTransaction(boolean doClose, long t0, String methodName) {
    
    357 359
             if (doClose) {
    
    358
    -            serviceContext.closeTransaction();
    
    360
    +            try {
    
    361
    +                serviceContext.closeTransaction();
    
    362
    +            } finally {
    
    363
    +                log(t0, "close transaction", methodName);
    
    364
    +            }
    
    359 365
             }
    
    360 366
         }
    
    361 367
     
    
    368
    +    protected final void logInvokeMethod(long t0, String methodName) {
    
    369
    +        log(t0, "invokeMethod", methodName);
    
    370
    +    }
    
    371
    +
    
    372
    +    protected final void log(long t0, String prefix, String methodName) {
    
    373
    +        TIME_LOG.log(t0, String.format("%s %s.%s", prefix, getClass().getName(), methodName));
    
    374
    +    }
    
    375
    +
    
    362 376
         protected final ObserveServiceContextLocal serviceContext() {
    
    363 377
             return serviceContext;
    
    364 378
         }
    

  • core/services/local/src/test/java/fr/ird/observe/services/local/service/api/DataEntityServiceLocalWriteTest.java
    ... ... @@ -22,11 +22,11 @@ package fr.ird.observe.services.local.service.api;
    22 22
      * #L%
    
    23 23
      */
    
    24 24
     
    
    25
    +import fr.ird.observe.dto.ToolkitId;
    
    25 26
     import fr.ird.observe.dto.data.DataDto;
    
    26 27
     import fr.ird.observe.dto.db.DataSourceValidationMode;
    
    27 28
     import fr.ird.observe.navigation.tree.io.ToolkitTreeNodeStates;
    
    28 29
     import fr.ird.observe.services.service.api.InvalidDataException;
    
    29
    -import fr.ird.observe.services.service.data.ps.common.TripService;
    
    30 30
     import fr.ird.observe.test.DatabaseName;
    
    31 31
     import fr.ird.observe.test.spi.CopyDatabaseConfiguration;
    
    32 32
     import fr.ird.observe.test.spi.DatabaseNameConfiguration;
    
    ... ... @@ -35,6 +35,7 @@ import org.junit.Test;
    35 35
     
    
    36 36
     import java.util.List;
    
    37 37
     import java.util.Map;
    
    38
    +import java.util.Objects;
    
    38 39
     
    
    39 40
     public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceLocalWriteTest {
    
    40 41
         @Override
    
    ... ... @@ -69,13 +70,13 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    69 70
         public void createPsTrip() throws InvalidDataException {
    
    70 71
             TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    71 72
             {
    
    72
    -            List<?> data = assertTrip(TripService.class,
    
    73
    -                                      fr.ird.observe.dto.data.ps.common.TripDto.class, "gearUseFeatures", 1);
    
    73
    +            List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    74
    +                                            fr.ird.observe.dto.data.ps.common.TripDto.class, "gearUseFeatures", 1);
    
    74 75
                 Assert.assertNotNull(data);
    
    75 76
             }
    
    76 77
             {
    
    77
    -            List<?> data = assertTrip(TripService.class,
    
    78
    -                                      fr.ird.observe.dto.data.ps.common.TripDto.class, "routeObs", 2);
    
    78
    +            List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    79
    +                                            fr.ird.observe.dto.data.ps.common.TripDto.class, "routeObs", 2);
    
    79 80
                 Assert.assertNotNull(data);
    
    80 81
             }
    
    81 82
         }
    
    ... ... @@ -88,13 +89,13 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    88 89
             TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    89 90
             try {
    
    90 91
                 {
    
    91
    -                List<?> data = assertTrip(TripService.class,
    
    92
    -                                          fr.ird.observe.dto.data.ps.common.TripDto.class, "routeLogbook", 1);
    
    92
    +                List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    93
    +                                                fr.ird.observe.dto.data.ps.common.TripDto.class, "routeLogbook", 1);
    
    93 94
                     Assert.assertNotNull(data);
    
    94 95
                 }
    
    95 96
                 {
    
    96
    -                Map<String, Object> data = assertTrip0(TripService.class,
    
    97
    -                                                       fr.ird.observe.dto.data.ps.common.TripDto.class, "all");
    
    97
    +                Map<String, Object> data = assertCreateTrip0(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    98
    +                                                             fr.ird.observe.dto.data.ps.common.TripDto.class, "all");
    
    98 99
                     Assert.assertNotNull(data);
    
    99 100
                 }
    
    100 101
             } finally {
    
    ... ... @@ -102,28 +103,55 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    102 103
             }
    
    103 104
         }
    
    104 105
     
    
    106
    +    @Test
    
    107
    +    @CopyDatabaseConfiguration
    
    108
    +    @DatabaseNameConfiguration(DatabaseName.referential)
    
    109
    +    public void updatePsTrip() throws InvalidDataException {
    
    110
    +        TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    111
    +        Map<?, ?> tripMap = null;
    
    112
    +        {
    
    113
    +            tripMap = assertCreateTrip0(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    114
    +                                        fr.ird.observe.dto.data.ps.common.TripDto.class, "gearUseFeatures");
    
    115
    +            Assert.assertNotNull(tripMap);
    
    116
    +        }
    
    117
    +        Objects.requireNonNull(tripMap);
    
    118
    +        String tripId = (String) tripMap.get(ToolkitId.PROPERTY_TOOLKIT_TOPIA_ID);
    
    119
    +        int exceptedRouteCount = 2;
    
    120
    +        {
    
    121
    +            List<?> data = assertUpdateTrip(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    122
    +                                            fr.ird.observe.dto.data.ps.common.TripDto.class, Objects.requireNonNull(tripId), "routeObs", exceptedRouteCount);
    
    123
    +            Assert.assertNotNull(data);
    
    124
    +        }
    
    125
    +        {
    
    126
    +            List<?> data = assertUpdateTrip(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    127
    +                                            fr.ird.observe.dto.data.ps.common.TripDto.class, Objects.requireNonNull(tripId), "routeObs", 2*exceptedRouteCount);
    
    128
    +            Assert.assertNotNull(data);
    
    129
    +        }
    
    130
    +        //FIXME Add more test for update https://gitlab.com/ultreiaio/ird-observe/-/issues/2171
    
    131
    +    }
    
    132
    +
    
    105 133
         @Test
    
    106 134
         @CopyDatabaseConfiguration
    
    107 135
         public void createLlTrip() throws InvalidDataException {
    
    108 136
             TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    109 137
             {
    
    110
    -            List<?> data = assertTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    111
    -                                      fr.ird.observe.dto.data.ll.common.TripDto.class, "gearUseFeatures", 1);
    
    138
    +            List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    139
    +                                            fr.ird.observe.dto.data.ll.common.TripDto.class, "gearUseFeatures", 1);
    
    112 140
                 Assert.assertNotNull(data);
    
    113 141
             }
    
    114 142
             {
    
    115
    -            List<?> data = assertTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    116
    -                                      fr.ird.observe.dto.data.ll.common.TripDto.class, "activityObs", 2);
    
    143
    +            List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    144
    +                                            fr.ird.observe.dto.data.ll.common.TripDto.class, "activityObs", 2);
    
    117 145
                 Assert.assertNotNull(data);
    
    118 146
             }
    
    119 147
             {
    
    120
    -            List<?> data = assertTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    121
    -                                      fr.ird.observe.dto.data.ll.common.TripDto.class, "activityLogbook", 2);
    
    148
    +            List<?> data = assertCreateTrip(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    149
    +                                            fr.ird.observe.dto.data.ll.common.TripDto.class, "activityLogbook", 2);
    
    122 150
                 Assert.assertNotNull(data);
    
    123 151
             }
    
    124 152
             {
    
    125
    -            Map<String, Object> data = assertTrip0(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    126
    -                                                   fr.ird.observe.dto.data.ll.common.TripDto.class, "all");
    
    153
    +            Map<String, Object> data = assertCreateTrip0(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    154
    +                                                         fr.ird.observe.dto.data.ll.common.TripDto.class, "all");
    
    127 155
                 Assert.assertNotNull(data);
    
    128 156
             }
    
    129 157
         }
    
    ... ... @@ -132,8 +160,8 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    132 160
         @CopyDatabaseConfiguration
    
    133 161
         public void createPsTripLinks() throws InvalidDataException {
    
    134 162
             TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    135
    -        Map<String, Object> data = assertTrip0(TripService.class,
    
    136
    -                                               fr.ird.observe.dto.data.ps.common.TripDto.class, "links");
    
    163
    +        Map<String, Object> data = assertCreateTrip0(fr.ird.observe.services.service.data.ps.common.TripService.class,
    
    164
    +                                                     fr.ird.observe.dto.data.ps.common.TripDto.class, "links");
    
    137 165
             Assert.assertNotNull(data);
    
    138 166
         }
    
    139 167
     
    
    ... ... @@ -141,13 +169,13 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    141 169
         @CopyDatabaseConfiguration
    
    142 170
         public void createLlTripLinks() throws InvalidDataException {
    
    143 171
             TOPIA_TEST_CLASS_RESOURCE.getServiceInitializerConfig().setValidationMode(DataSourceValidationMode.NONE);
    
    144
    -        Map<String, Object> data = assertTrip0(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    145
    -                                               fr.ird.observe.dto.data.ll.common.TripDto.class, "links");
    
    172
    +        Map<String, Object> data = assertCreateTrip0(fr.ird.observe.services.service.data.ll.common.TripService.class,
    
    173
    +                                                     fr.ird.observe.dto.data.ll.common.TripDto.class, "links");
    
    146 174
             Assert.assertNotNull(data);
    
    147 175
         }
    
    148 176
     
    
    149
    -    protected List<?> assertTrip(Class<?> serviceType, Class<? extends DataDto> dtoType, String classifier, int expectedCount) throws InvalidDataException {
    
    150
    -        Map<String, Object> resultObject = assertTrip0(serviceType, dtoType, classifier);
    
    177
    +    protected List<?> assertCreateTrip(Class<?> serviceType, Class<? extends DataDto> dtoType, String classifier, int expectedCount) throws InvalidDataException {
    
    178
    +        Map<String, Object> resultObject = assertCreateTrip0(serviceType, dtoType, classifier);
    
    151 179
             Assert.assertNotNull(resultObject);
    
    152 180
     
    
    153 181
             List<?> data = (List<?>) resultObject.get(classifier);
    
    ... ... @@ -156,7 +184,8 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    156 184
             return data;
    
    157 185
         }
    
    158 186
     
    
    159
    -    protected Map<String, Object> assertTrip0(Class<?> serviceType, Class<? extends DataDto> dtoType, String classifier) throws InvalidDataException {
    
    187
    +
    
    188
    +    protected Map<String, Object> assertCreateTrip0(Class<?> serviceType, Class<? extends DataDto> dtoType, String classifier) throws InvalidDataException {
    
    160 189
             String json = fixtures.loadContent(serviceType, classifier);
    
    161 190
             ToolkitTreeNodeStates result = fixtures.testCreate(service, dtoType, json);
    
    162 191
             String content = result.getState("content");
    
    ... ... @@ -166,4 +195,25 @@ public class DataEntityServiceLocalWriteTest extends GeneratedDataEntityServiceL
    166 195
             return resultObject;
    
    167 196
     
    
    168 197
         }
    
    198
    +
    
    199
    +    protected List<?> assertUpdateTrip(Class<?> serviceType, Class<? extends DataDto> dtoType, String id, String classifier, int expectedCount) throws InvalidDataException {
    
    200
    +        Map<String, Object> resultObject = assertUpdateTrip0(serviceType, dtoType, id, classifier);
    
    201
    +        Assert.assertNotNull(resultObject);
    
    202
    +
    
    203
    +        List<?> data = (List<?>) resultObject.get(classifier);
    
    204
    +        Assert.assertNotNull(data);
    
    205
    +        Assert.assertEquals(expectedCount, data.size());
    
    206
    +        return data;
    
    207
    +    }
    
    208
    +
    
    209
    +    protected Map<String, Object> assertUpdateTrip0(Class<?> serviceType, Class<? extends DataDto> dtoType, String id, String classifier) throws InvalidDataException {
    
    210
    +        String json = fixtures.loadContent(serviceType, classifier);
    
    211
    +        ToolkitTreeNodeStates result = fixtures.testUpdate(service, dtoType, id, json);
    
    212
    +        String content = result.getState("content");
    
    213
    +        Assert.assertNotNull(content);
    
    214
    +        @SuppressWarnings("unchecked") Map<String, Object> resultObject = (Map<String, Object>) fixtures.fromJsonList(content).get(0);
    
    215
    +        Assert.assertNotNull(resultObject);
    
    216
    +        return resultObject;
    
    217
    +
    
    218
    +    }
    
    169 219
     }

  • core/services/test/src/main/java/fr/ird/observe/services/service/api/DataEntityServiceFixtures.java
    ... ... @@ -378,7 +378,7 @@ public class DataEntityServiceFixtures extends GeneratedDataEntityServiceFixture
    378 378
                     }
    
    379 379
                     try {
    
    380 380
                         String content = loadFixture(module, subModule, dtoType, "content.json");
    
    381
    -                    testUpdate(service, dtoType, content);
    
    381
    +                    testUpdate(service, dtoType, null, content);
    
    382 382
                     } catch (IOException e) {
    
    383 383
                         log.warn(String.format("No fixture for %s", dtoType));
    
    384 384
                     } catch (InvalidDataException e) {
    
    ... ... @@ -404,11 +404,14 @@ public class DataEntityServiceFixtures extends GeneratedDataEntityServiceFixture
    404 404
             return getResult;
    
    405 405
         }
    
    406 406
     
    
    407
    -    public ToolkitTreeNodeStates testUpdate(DataEntityService service, Class<? extends DataDto> dtoType, String content) throws InvalidDataException {
    
    407
    +    public ToolkitTreeNodeStates testUpdate(DataEntityService service, Class<? extends DataDto> dtoType, String id, String content) throws InvalidDataException {
    
    408 408
             log.debug(String.format("for type: %s", dtoType.getName()));
    
    409 409
             Pair<String, List<Object>> result = JsonHelper.removeAndCollectProperties(gson, content, ToolkitId.PROPERTY_TOOLKIT_TOPIA_ID, ToolkitId.PROPERTY_TOOLKIT_CREATE_DATE, ToolkitId.PROPERTY_TOOLKIT_LAST_UPDATE_DATE);
    
    410 410
             content = result.getKey();
    
    411
    -        String id = (String) result.getValue().get(0);
    
    411
    +        if (id==null) {
    
    412
    +
    
    413
    +            id = (String) result.getValue().get(0);
    
    414
    +        }
    
    412 415
             ToolkitId actual = service.update(dtoType, Objects.requireNonNull(id), content);
    
    413 416
             Assert.assertNotNull(actual);
    
    414 417
             Assert.assertEquals(id, actual.getTopiaId());
    

  • pom.xml
    ... ... @@ -23,7 +23,7 @@
    23 23
       <parent>
    
    24 24
         <groupId>io.ultreia.maven</groupId>
    
    25 25
         <artifactId>pom</artifactId>
    
    26
    -    <version>2022.21</version>
    
    26
    +    <version>2022.22</version>
    
    27 27
       </parent>
    
    28 28
       <groupId>fr.ird.observe</groupId>
    
    29 29
       <artifactId>ird-observe</artifactId>
    
    ... ... @@ -155,7 +155,7 @@
    155 155
         <!-- build timestamp configuration -->
    
    156 156
         <maven.build.timestamp.format>dd/MM/yyyy HH:mm z</maven.build.timestamp.format>
    
    157 157
         <buildDate>${maven.build.timestamp}</buildDate>
    
    158
    -    <lib.version.toolkit>6.0.2</lib.version.toolkit>
    
    158
    +    <lib.version.toolkit>6.0.3</lib.version.toolkit>
    
    159 159
         <lib.version.ognl>3.1.29</lib.version.ognl>
    
    160 160
         <!--can't use 1.4.197 (date has changed + blob also)-->
    
    161 161
         <lib.version.h2>1.4.196</lib.version.h2>
    

  • server/configuration-tools/README.md
    ... ... @@ -29,7 +29,7 @@ sh default-migrate-server-v7.sh
    29 29
     
    
    30 30
     ## Optimize v9 server configuration file
    
    31 31
     
    
    32
    -v9 **security.yml** file can be optimize.
    
    32
    +v9 **security.yml** file can be optimized.
    
    33 33
     
    
    34 34
     Run the script **optimize-server-v9.sh** for this purpose.
    
    35 35
     
    

  • server/configuration/src/main/java/fr/ird/observe/server/configuration/ServerConfig.java
    ... ... @@ -90,7 +90,7 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    90 90
             fakeConfig.initFirst();
    
    91 91
     
    
    92 92
             // Now that common files are ready, starts a normal configuration without system file and without migration possible
    
    93
    -        ApplicationConfigInit  realInit = ApplicationConfigInit.forAllScopesWithout(ApplicationConfigScope.HOME, ApplicationConfigScope.ENV, ApplicationConfigScope.SYSTEM)
    
    93
    +        ApplicationConfigInit realInit = ApplicationConfigInit.forAllScopesWithout(ApplicationConfigScope.HOME, ApplicationConfigScope.ENV, ApplicationConfigScope.SYSTEM)
    
    94 94
                     .addDefaults(ServerConfigOption.CONTEXT_PATH.getKey(), contextPath);
    
    95 95
     
    
    96 96
             ServerConfig config = new ServerConfig(setInstanceExtraConfigDirectory(setConfigFileName(realInit)));
    
    ... ... @@ -133,22 +133,22 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    133 133
         }
    
    134 134
     
    
    135 135
         public void initFirst() {
    
    136
    -        log.info("Starts to init ObServe fake server configuration (to generate default directories and common files...");
    
    136
    +        log.info("Starts to init ObServe fake server configuration (to generate default directories and common files...)");
    
    137 137
     
    
    138 138
             parse();
    
    139 139
     
    
    140 140
             Path baseDirectory = getCommonConfigDirectory().toPath();
    
    141
    -        createDirectories(baseDirectory, "Impossible de créer le répertoire principal de l'application (%s)");
    
    141
    +        createDirectories(baseDirectory, "Could not create application main directory (%s)");
    
    142 142
     
    
    143 143
             File extraConfigFile = get().getExtraConfigFile();
    
    144 144
             if (Files.notExists(extraConfigFile.toPath())) {
    
    145 145
                 log.info(String.format("Save common configuration file to: %s", extraConfigFile));
    
    146
    -            ConfigHelper.save(get(), extraConfigFile, new String[0], ServerResources.CONFIG, options());
    
    146
    +            ConfigHelper.save(get(), extraConfigFile, new String[0], ServerResources.APPLICATION_CONFIGURATION, options());
    
    147 147
             }
    
    148 148
     
    
    149 149
             File log4jConfigurationFile = getCommonLog4jConfigurationFile();
    
    150 150
             if (!log4jConfigurationFile.exists()) {
    
    151
    -            ServerResources.LOG_CONFIGURATION_FILE.copyResource(log4jConfigurationFile);
    
    151
    +            ServerResources.LOG_CONFIGURATION.copyResource(log4jConfigurationFile);
    
    152 152
                 log.info(String.format("Generate empty log4j configuration file to: %s", log4jConfigurationFile));
    
    153 153
             }
    
    154 154
         }
    
    ... ... @@ -160,11 +160,11 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    160 160
     
    
    161 161
             Path baseDirectory = getBaseDirectory().toPath();
    
    162 162
             log.info(getConfigurationDescription());
    
    163
    -        createDirectories(baseDirectory, "Impossible de créer le répertoire principal de l'application (%s)");
    
    163
    +        createDirectories(baseDirectory, "Could not create application instance directory (%s)");
    
    164 164
     
    
    165 165
             File extraConfigFile = get().getExtraConfigFile();
    
    166 166
             if (Files.notExists(extraConfigFile.toPath())) {
    
    167
    -            boolean generated = ServerResources.CONFIG.copyResource(getCommonConfigurationFile().toPath(), extraConfigFile);
    
    167
    +            boolean generated = ServerResources.APPLICATION_CONFIGURATION.copyResource(getCommonConfigurationFile().toPath(), extraConfigFile);
    
    168 168
                 if (generated) {
    
    169 169
                     log.info(String.format("Generate empty configuration file to: %s", extraConfigFile));
    
    170 170
                 } else {
    
    ... ... @@ -173,7 +173,7 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    173 173
             }
    
    174 174
     
    
    175 175
             Path temporaryDirectory = getTemporaryDirectory().toPath();
    
    176
    -        createDirectories(temporaryDirectory, "Impossible de créer le répertoire temporaire (%s)");
    
    176
    +        createDirectories(temporaryDirectory, "Could not create temporary directory (%s)");
    
    177 177
     
    
    178 178
             File securityConfigurationFile = getSecurityConfigurationFile();
    
    179 179
             if (!securityConfigurationFile.exists()) {
    
    ... ... @@ -181,7 +181,7 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    181 181
                 if (strict && !commonSecurityConfigurationFile.exists()) {
    
    182 182
                     throw new IllegalStateException(String.format("Can not start application. Could not find security.yml file.\n\nPlease add it to one of this places:\n\t%s\n\t%s", commonSecurityConfigurationFile, securityConfigurationFile));
    
    183 183
                 }
    
    184
    -            boolean generated = ServerResources.SECURITY.copyResource(commonSecurityConfigurationFile.toPath(), securityConfigurationFile);
    
    184
    +            boolean generated = ServerResources.SECURITY_CONFIGURATION.setStrict(strict).copyResource(commonSecurityConfigurationFile.toPath(), securityConfigurationFile);
    
    185 185
                 if (generated) {
    
    186 186
                     log.info("Generate default security.yml");
    
    187 187
                 } else {
    
    ... ... @@ -192,28 +192,37 @@ public class ServerConfig extends GeneratedServerConfig implements CleanTemporar
    192 192
             log.info("ObServe server configuration init done.");
    
    193 193
         }
    
    194 194
     
    
    195
    +    public ReferentialLocale getReferentialLocale() {
    
    196
    +        if (referentialLocale == null) {
    
    197
    +            referentialLocale = ReferentialLocale.valueOf(getDbLocale());
    
    198
    +        }
    
    199
    +        return referentialLocale;
    
    200
    +    }
    
    201
    +
    
    202
    +    public String getConfigurationContent() throws IOException {
    
    203
    +        Path path = get().getExtraConfigFile().toPath();
    
    204
    +        return Files.readString(path);
    
    205
    +    }
    
    206
    +
    
    207
    +    public String getSecurityContent() throws IOException {
    
    208
    +        Path path = getSecurityConfigurationFile().toPath();
    
    209
    +        return Files.readString(path);
    
    210
    +    }
    
    211
    +
    
    195 212
         private void parse() {
    
    196 213
             try {
    
    197 214
                 get().parse();
    
    198 215
             } catch (ArgumentsParserException e) {
    
    199 216
                 throw new ObserveWebApplicationConfigInitException("could not parse configuration", e);
    
    200 217
             }
    
    201
    -
    
    202 218
         }
    
    203 219
     
    
    204 220
         private void initLog() {
    
    205 221
             File logFile = getLog4jConfigurationFile();
    
    206 222
             log.info(String.format("Chargement du fichier de log : %s", logFile));
    
    207
    -        ObserveUtil.loadLogConfiguration(ServerResources.LOG_CONFIGURATION_FILE, getCommonLog4jConfigurationFile().toPath(), logFile.toPath(), this);
    
    223
    +        ObserveUtil.loadLogConfiguration(ServerResources.LOG_CONFIGURATION, getCommonLog4jConfigurationFile().toPath(), logFile.toPath(), this);
    
    208 224
             log = LogManager.getLogger(ServerConfig.class);
    
    209 225
             log.info(String.format("Configuration des logs chargée depuis le fichier %s", logFile));
    
    210 226
         }
    
    211 227
     
    
    212
    -    public ReferentialLocale getReferentialLocale() {
    
    213
    -        if (referentialLocale == null) {
    
    214
    -            referentialLocale = ReferentialLocale.valueOf(getDbLocale());
    
    215
    -        }
    
    216
    -        return referentialLocale;
    
    217
    -    }
    
    218
    -
    
    219 228
     }

  • server/configuration/src/main/java/fr/ird/observe/server/configuration/ServerResources.java
    ... ... @@ -24,6 +24,10 @@ package fr.ird.observe.server.configuration;
    24 24
     
    
    25 25
     import io.ultreia.java4all.config.ConfigResource;
    
    26 26
     
    
    27
    +import java.io.File;
    
    28
    +import java.nio.file.Files;
    
    29
    +import java.nio.file.Path;
    
    30
    +
    
    27 31
     /**
    
    28 32
      * Created on 07/12/2021.
    
    29 33
      *
    
    ... ... @@ -31,7 +35,33 @@ import io.ultreia.java4all.config.ConfigResource;
    31 35
      * @since 9.0.0
    
    32 36
      */
    
    33 37
     public class ServerResources {
    
    34
    -    public static final ConfigResource CONFIG = new ConfigResource("/META-INF/configuration/observe-server.conf");
    
    35
    -    public static final ConfigResource SECURITY = new ConfigResource("/defaultSecurity.yml");
    
    36
    -    public static final ConfigResource LOG_CONFIGURATION_FILE = new ConfigResource("/log.xml");
    
    38
    +    public static final ConfigResource APPLICATION_CONFIGURATION = new ConfigResource("/META-INF/configuration/observe-server.conf");
    
    39
    +    public static final ConfigResource2 SECURITY_CONFIGURATION = new ConfigResource2("/META-INF/configuration/security.yml");
    
    40
    +    public static final ConfigResource LOG_CONFIGURATION = new ConfigResource("/META-INF/configuration/log.xml");
    
    41
    +
    
    42
    +    static class ConfigResource2 extends ConfigResource {
    
    43
    +
    
    44
    +        private boolean strict;
    
    45
    +
    
    46
    +        public ConfigResource2(String location) {
    
    47
    +            super(location);
    
    48
    +        }
    
    49
    +
    
    50
    +        public boolean isStrict() {
    
    51
    +            return strict;
    
    52
    +        }
    
    53
    +
    
    54
    +        public ConfigResource2 setStrict(boolean strict) {
    
    55
    +            this.strict = strict;
    
    56
    +            return this;
    
    57
    +        }
    
    58
    +
    
    59
    +        @Override
    
    60
    +        public boolean copyResource(Path sharedFile, File file) {
    
    61
    +            if (isStrict() && Files.notExists(sharedFile)) {
    
    62
    +                throw new IllegalStateException(String.format("You are not allowed to copy this resource: %s", this));
    
    63
    +            }
    
    64
    +            return super.copyResource(sharedFile, file);
    
    65
    +        }
    
    66
    +    }
    
    37 67
     }

  • server/configuration/src/test/resources/log.xmlserver/configuration/src/test/resources/META-INF/configuration/log.xml

  • server/configuration/src/main/resources/defaultSecurity.ymlserver/configuration/src/test/resources/META-INF/configuration/security.yml

  • server/core/src/main/java/fr/ird/observe/server/controller/AdminController.java
    ... ... @@ -23,8 +23,6 @@ package fr.ird.observe.server.controller;
    23 23
      */
    
    24 24
     
    
    25 25
     import fr.ird.observe.dto.server.InvalidServerModelException;
    
    26
    -import fr.ird.observe.dto.server.ServerModel;
    
    27
    -import fr.ird.observe.dto.server.ServerModelHelper;
    
    28 26
     import fr.ird.observe.server.security.ObserveWebSecurityApplicationContext;
    
    29 27
     import fr.ird.observe.server.security.ObserveWebUserSession;
    
    30 28
     import fr.ird.observe.spi.RenderMarkdown;
    
    ... ... @@ -54,7 +52,7 @@ public class AdminController extends ObserveWebMotionController {
    54 52
         public RenderContent configuration() throws IOException {
    
    55 53
             StringBuilder builder = new StringBuilder();
    
    56 54
             builder.append("\n## Configuration\n");
    
    57
    -        String content = getApplicationConfiguration().getConfigurationDescription();
    
    55
    +        String content = getApplicationConfiguration().getConfigurationContent();
    
    58 56
             builder.append(String.format("\n```properties\n%s\n```", content));
    
    59 57
             return toHtml(RenderMarkdown.renderContent(builder.toString()));
    
    60 58
         }
    
    ... ... @@ -77,8 +75,7 @@ public class AdminController extends ObserveWebMotionController {
    77 75
             builder.append("\n## Fichier de définition du sécurité\n");
    
    78 76
             File securityConfigurationFile = getApplicationConfiguration().getSecurityConfigurationFile();
    
    79 77
             builder.append(String.format("\nEmplacement : %s\n", securityConfigurationFile));
    
    80
    -        ServerModel securityModel = ServerModelHelper.load(securityConfigurationFile);
    
    81
    -        String content = ServerModelHelper.toString(securityModel);
    
    78
    +        String content = getApplicationConfiguration().getSecurityContent();
    
    82 79
             builder.append(String.format("\n```yaml\n%s\n```", content));
    
    83 80
             return toHtml(RenderMarkdown.renderContent(builder.toString()));
    
    84 81
         }
    

  • server/core/src/main/java/fr/ird/observe/server/security/ObserveWebSecurityApplicationContext.java
    ... ... @@ -26,8 +26,6 @@ import fr.ird.observe.dto.db.DataSourceApiAccess;
    26 26
     import fr.ird.observe.dto.db.configuration.ObserveDataSourceConnection;
    
    27 27
     import fr.ird.observe.dto.referential.ReferentialLocale;
    
    28 28
     import fr.ird.observe.dto.server.ServerModel;
    
    29
    -import fr.ird.observe.dto.server.security.InvalidApiAccessException;
    
    30
    -import fr.ird.observe.dto.server.security.InvalidAuthenticationTokenException;
    
    31 29
     import fr.ird.observe.server.configuration.ServerConfig;
    
    32 30
     import io.ultreia.java4all.util.Version;
    
    33 31
     
    
    ... ... @@ -38,7 +36,15 @@ import java.util.Collection;
    38 36
     import java.util.Locale;
    
    39 37
     
    
    40 38
     /**
    
    41
    - * Pour conserver les données applicatives liée à la sécurité (principale le cache des utilisateurs connectés).
    
    39
    + * Application security context.
    
    40
    + * <p>
    
    41
    + * Manages
    
    42
    + *
    
    43
    + * <ul>
    
    44
    + *     <li>a cache of configuration ({@link #configurationCache}, to init a new session from an available configuration)</li>
    
    45
    + *     <li>a cache of session ({@link #authenticateCache} to keep authenticated session)</li>
    
    46
    + * </ul>
    
    47
    + *
    
    42 48
      * <p>
    
    43 49
      * Created on 30/08/15.
    
    44 50
      *
    
    ... ... @@ -46,17 +52,14 @@ import java.util.Locale;
    46 52
      */
    
    47 53
     public class ObserveWebSecurityApplicationContext implements Closeable {
    
    48 54
     
    
    49
    -    /**
    
    50
    -     * Cache of session.
    
    51
    -     */
    
    52
    -    protected final ObserveWebSecuritySessionCache authenticateCache;
    
    53
    -
    
    54 55
         /**
    
    55 56
          * Cache of available configurations.
    
    56
    -     *
    
    57
    -     * @see ObserveWebSecurityConfigCache
    
    58 57
          */
    
    59 58
         protected final ObserveWebSecurityConfigCache configurationCache;
    
    59
    +    /**
    
    60
    +     * Cache of session.
    
    61
    +     */
    
    62
    +    protected final ObserveWebSecuritySessionCache authenticateCache;
    
    60 63
     
    
    61 64
         public ObserveWebSecurityApplicationContext(ServerConfig configuration) {
    
    62 65
             this.authenticateCache = new ObserveWebSecuritySessionCache(configuration.getSessionExpirationDelay());
    
    ... ... @@ -64,7 +67,7 @@ public class ObserveWebSecurityApplicationContext implements Closeable {
    64 67
         }
    
    65 68
     
    
    66 69
         public synchronized void init(Path temporaryDirectory, ServerModel serverModel, Version modelVersion) {
    
    67
    -        authenticateCache.removeAllSessions();
    
    70
    +        authenticateCache.close();
    
    68 71
             configurationCache.load(serverModel, modelVersion, temporaryDirectory);
    
    69 72
         }
    
    70 73
     
    
    ... ... @@ -74,8 +77,8 @@ public class ObserveWebSecurityApplicationContext implements Closeable {
    74 77
     
    
    75 78
         public ObserveWebUserSession newConfigurationSession(ObserveWebUserSession anonymousSession, String userLogin, String userPassword, String optionalDatabaseName) {
    
    76 79
             Locale locale = anonymousSession.getApplicationLocale();
    
    77
    -        ObserveWebSecurityConfigCacheKey configCacheKey = configurationCache.getEntry(locale, userLogin, optionalDatabaseName, userPassword);
    
    78
    -        return anonymousSession.toConfigurationSession(configCacheKey);
    
    80
    +        ObserveWebSecurityConfigCacheValue cacheValue = configurationCache.getValue(locale, userLogin, optionalDatabaseName, userPassword);
    
    81
    +        return anonymousSession.toConfigurationSession(cacheValue);
    
    79 82
         }
    
    80 83
     
    
    81 84
         public ObserveWebUserSession registerAuthenticatedSession(ObserveWebUserSession configurationSession, ObserveDataSourceConnection connection) {
    
    ... ... @@ -89,14 +92,7 @@ public class ObserveWebSecurityApplicationContext implements Closeable {
    89 92
         }
    
    90 93
     
    
    91 94
         public ObserveWebUserSession getSession(Locale locale, String authenticationToken, DataSourceApiAccess requestApiAccess) {
    
    92
    -        ObserveWebUserSession session = authenticateCache.getSessionIfPresent(authenticationToken);
    
    93
    -        if (session == null) {
    
    94
    -            throw new InvalidAuthenticationTokenException(locale, authenticationToken);
    
    95
    -        }
    
    96
    -        if (session.rejectApiAccess(requestApiAccess)) {
    
    97
    -            throw new InvalidApiAccessException(locale, requestApiAccess, session.getUserPermission().getApiAccess());
    
    98
    -        }
    
    99
    -        return session;
    
    95
    +        return authenticateCache.getSession(locale, authenticationToken, requestApiAccess);
    
    100 96
         }
    
    101 97
     
    
    102 98
         public void invalidateAuthenticationToken(String authenticationToken) {
    

  • server/core/src/main/java/fr/ird/observe/server/security/ObserveWebSecurityConfigCache.java
    ... ... @@ -22,7 +22,6 @@ package fr.ird.observe.server.security;
    22 22
      * #L%
    
    23 23
      */
    
    24 24
     
    
    25
    -import com.google.common.base.Strings;
    
    26 25
     import fr.ird.observe.dto.db.configuration.ObserveDataSourceConfiguration;
    
    27 26
     import fr.ird.observe.dto.db.configuration.topia.ObserveDataSourceConfigurationTopiaPG;
    
    28 27
     import fr.ird.observe.dto.server.ServerDatabase;
    
    ... ... @@ -35,6 +34,7 @@ import fr.ird.observe.dto.server.security.UnknownObserveWebUserException;
    35 34
     import fr.ird.observe.dto.server.security.UnknownObserveWebUserForDatabaseException;
    
    36 35
     import fr.ird.observe.dto.server.security.UserLoginNotFoundException;
    
    37 36
     import fr.ird.observe.dto.server.security.UserPasswordNotFoundException;
    
    37
    +import io.ultreia.java4all.lang.Strings;
    
    38 38
     import io.ultreia.java4all.util.Version;
    
    39 39
     import org.apache.logging.log4j.LogManager;
    
    40 40
     import org.apache.logging.log4j.Logger;
    
    ... ... @@ -48,7 +48,11 @@ import java.util.TreeMap;
    48 48
     import java.util.TreeSet;
    
    49 49
     
    
    50 50
     /**
    
    51
    - * Cache of security config.
    
    51
    + * Cache of security config, build from the {@code security.yml} file.
    
    52
    + * <p>
    
    53
    + * The method {@link #load(ServerModel, Version, Path)} load once for all the security model in the {@link #cache}.
    
    54
    + * <p>
    
    55
    + * After that, to get a configuration, use the method {@link #getKey(String, String)}.
    
    52 56
      * <p>
    
    53 57
      * Created on 19/12/2021.
    
    54 58
      *
    
    ... ... @@ -60,25 +64,32 @@ public class ObserveWebSecurityConfigCache {
    60 64
         private static final Logger log = LogManager.getLogger(ObserveWebSecurityConfigCache.class);
    
    61 65
     
    
    62 66
         /**
    
    63
    -     * Le cache des configurations disponibles pour les couple (utilisateur#base) connus du système.
    
    67
    +     * Available configurations indexed by the key {@code login--databaseName}, values of configurations.
    
    64 68
          *
    
    65
    -     * @see #getUserKey(String, String)
    
    69
    +     * @see #getKey(String, String) to get a cache key
    
    70
    +     */
    
    71
    +    protected final Map<String, ObserveWebSecurityConfigCacheValue> cache;
    
    72
    +    /**
    
    73
    +     * Available logins (used to check if login exists)
    
    66 74
          */
    
    67
    -    protected final Map<String, ObserveWebSecurityConfigCacheKey> cache;
    
    68 75
         protected final Set<String> availableUserLogin;
    
    69 76
         /**
    
    70
    -     * Le nom de la base par défaut à utiliser si elle n'est pas spécifiée.
    
    77
    +     * Default database name (defined in {@code security.yml}), used if non database is given in a request).
    
    71 78
          *
    
    72 79
          * @see ServerModel#getDefaultDatabase()
    
    73 80
          */
    
    74 81
         protected String defaultDatabaseName;
    
    75 82
     
    
    83
    +    protected static String getKey(String userLogin, String databaseName) {
    
    84
    +        return userLogin + "--" + databaseName;
    
    85
    +    }
    
    86
    +
    
    76 87
         public ObserveWebSecurityConfigCache() {
    
    77 88
             this.cache = new TreeMap<>();
    
    78 89
             this.availableUserLogin = new TreeSet<>();
    
    79 90
         }
    
    80 91
     
    
    81
    -    public void load(ServerModel serverModel, Version modelVersion, Path temporaryDirectory) {
    
    92
    +    protected void load(ServerModel serverModel, Version modelVersion, Path temporaryDirectory) {
    
    82 93
             cache.clear();
    
    83 94
             availableUserLogin.clear();
    
    84 95
     
    
    ... ... @@ -95,7 +106,7 @@ public class ObserveWebSecurityConfigCache {
    95 106
                     String jdbcUrl = database.getUrl();
    
    96 107
                     String login = role.getLogin();
    
    97 108
                     String password = role.getPassword();
    
    98
    -                String userKey = getUserKey(serverUser.getLogin(), database.getName());
    
    109
    +                String userKey = getKey(serverUser.getLogin(), database.getName());
    
    99 110
     
    
    100 111
                     // Create DataSourceConfiguration
    
    101 112
                     ObserveDataSourceConfiguration configuration = ObserveDataSourceConfigurationTopiaPG.create(
    
    ... ... @@ -108,17 +119,18 @@ public class ObserveWebSecurityConfigCache {
    108 119
                             true,
    
    109 120
                             modelVersion);
    
    110 121
                     configuration.setTemporaryDirectory(temporaryDirectory);
    
    122
    +                ObserveWebSecurityConfigCacheValue value = new ObserveWebSecurityConfigCacheValue(serverUser, serverUserPermission, configuration);
    
    111 123
                     log.info(String.format("Creates data source configuration for userKey %s : %s", userKey, configuration));
    
    112
    -                cache.put(userKey, new ObserveWebSecurityConfigCacheKey(serverUser, serverUserPermission, configuration));
    
    124
    +                cache.put(userKey, value);
    
    113 125
                 }
    
    114 126
             }
    
    115 127
         }
    
    116 128
     
    
    117
    -    public ObserveWebSecurityConfigCacheKey getEntry(Locale locale, String userLogin, String databaseName, String userPassword) {
    
    118
    -        if (Strings.isNullOrEmpty(userLogin)) {
    
    129
    +    protected ObserveWebSecurityConfigCacheValue getValue(Locale locale, String userLogin, String databaseName, String userPassword) {
    
    130
    +        if (Strings.isEmpty(userLogin)) {
    
    119 131
                 throw new UserLoginNotFoundException(locale);
    
    120 132
             }
    
    121
    -        if (Strings.isNullOrEmpty(userPassword)) {
    
    133
    +        if (Strings.isEmpty(userPassword)) {
    
    122 134
                 throw new UserPasswordNotFoundException(locale);
    
    123 135
             }
    
    124 136
             if (!availableUserLogin.contains(userLogin)) {
    
    ... ... @@ -127,21 +139,18 @@ public class ObserveWebSecurityConfigCache {
    127 139
             if (databaseName == null) {
    
    128 140
                 databaseName = defaultDatabaseName;
    
    129 141
             }
    
    130
    -        String userKey = getUserKey(userLogin, databaseName);
    
    131
    -        log.info(String.format("Try to find data source configuration for: %s", userKey));
    
    132
    -        ObserveWebSecurityConfigCacheKey configCacheKey = cache.get(userKey);
    
    133
    -        if (configCacheKey == null) {
    
    142
    +        String cacheKey = getKey(userLogin, databaseName);
    
    143
    +        log.info(String.format("Try to find data source configuration for: %s", cacheKey));
    
    144
    +        ObserveWebSecurityConfigCacheValue cacheValue = cache.get(cacheKey);
    
    145
    +        if (cacheValue == null) {
    
    134 146
                 throw new UnknownObserveWebUserForDatabaseException(locale, databaseName, userLogin);
    
    135 147
             }
    
    136
    -        ServerUser user = configCacheKey.getServerUser();
    
    148
    +        ServerUser user = cacheValue.getServerUser();
    
    149
    +        //FIXME In the cache do not keep real password but a hash
    
    137 150
             if (!Objects.equals(user.getPassword(), userPassword)) {
    
    138 151
                 throw new BadObserveWebUserPasswordException(locale, userLogin);
    
    139 152
             }
    
    140
    -        log.info(String.format("Will use database configuration: %s", configCacheKey.getConfiguration()));
    
    141
    -        return configCacheKey;
    
    142
    -    }
    
    143
    -
    
    144
    -    public String getUserKey(String userLogin, String databaseName) {
    
    145
    -        return userLogin + "--" + databaseName;
    
    153
    +        log.info(String.format("Will use database configuration: %s", cacheValue.getConfiguration()));
    
    154
    +        return cacheValue;
    
    146 155
         }
    
    147 156
     }

  • server/core/src/main/java/fr/ird/observe/server/security/ObserveWebSecurityConfigCacheKey.javaserver/core/src/main/java/fr/ird/observe/server/security/ObserveWebSecurityConfigCacheValue.java
    ... ... @@ -26,21 +26,34 @@ import fr.ird.observe.dto.db.configuration.ObserveDataSourceConfiguration;
    26 26
     import fr.ird.observe.dto.server.ServerUser;
    
    27 27
     import fr.ird.observe.dto.server.ServerUserPermission;
    
    28 28
     
    
    29
    +import java.util.Objects;
    
    30
    +
    
    29 31
     /**
    
    32
    + * Represents a value in the {@link ObserveWebSecurityConfigCache}.
    
    33
    + * <p>
    
    30 34
      * Created on 19/12/2021.
    
    31 35
      *
    
    32 36
      * @author Tony Chemit - dev@tchemit.fr
    
    33 37
      * @since 9.0.0
    
    34 38
      */
    
    35
    -public class ObserveWebSecurityConfigCacheKey {
    
    39
    +public class ObserveWebSecurityConfigCacheValue {
    
    40
    +    /**
    
    41
    +     * User.
    
    42
    +     */
    
    36 43
         private final ServerUser serverUser;
    
    44
    +    /**
    
    45
    +     * User permission.
    
    46
    +     */
    
    37 47
         private final ServerUserPermission serverUserPermission;
    
    48
    +    /**
    
    49
    +     * Data source configuration.
    
    50
    +     */
    
    38 51
         private final ObserveDataSourceConfiguration configuration;
    
    39 52
     
    
    40
    -    ObserveWebSecurityConfigCacheKey(ServerUser serverUser, ServerUserPermission serverUserPermission, ObserveDataSourceConfiguration configuration) {
    
    41
    -        this.serverUser = serverUser;
    
    42
    -        this.serverUserPermission = serverUserPermission;
    
    43
    -        this.configuration = configuration;
    
    53
    +    ObserveWebSecurityConfigCacheValue(ServerUser serverUser, ServerUserPermission serverUserPermission, ObserveDataSourceConfiguration configuration) {
    
    54
    +        this.serverUser = Objects.requireNonNull(serverUser);
    
    55
    +        this.serverUserPermission = Objects.requireNonNull(serverUserPermission);
    
    56
    +        this.configuration = Objects.requireNonNull(configuration);
    
    44 57
         }
    
    45 58
     
    
    46 59
         public ServerUser getServerUser() {
    

  • server/core/src/main/java/fr/ird/observe/server/security/ObserveWebSecuritySessionCache.java
    ... ... @@ -25,14 +25,18 @@ package fr.ird.observe.server.security;
    25 25
     import com.google.common.cache.Cache;
    
    26 26
     import com.google.common.cache.CacheBuilder;
    
    27 27
     import com.google.common.cache.RemovalListener;
    
    28
    +import fr.ird.observe.dto.db.DataSourceApiAccess;
    
    29
    +import fr.ird.observe.dto.server.security.InvalidApiAccessException;
    
    30
    +import fr.ird.observe.dto.server.security.InvalidAuthenticationTokenException;
    
    28 31
     import org.apache.logging.log4j.LogManager;
    
    29 32
     import org.apache.logging.log4j.Logger;
    
    30 33
     
    
    31 34
     import java.io.Closeable;
    
    35
    +import java.util.Locale;
    
    32 36
     import java.util.concurrent.TimeUnit;
    
    33 37
     
    
    34 38
     /**
    
    35
    - * Cache of use session.
    
    39
    + * Cache of user session.
    
    36 40
      * <p>
    
    37 41
      * Created on 30/08/15.
    
    38 42
      *
    
    ... ... @@ -49,30 +53,37 @@ public class ObserveWebSecuritySessionCache implements Closeable {
    49 53
     
    
    50 54
         public ObserveWebSecuritySessionCache(int expireDelay) {
    
    51 55
             this.sessionCache = CacheBuilder.newBuilder()
    
    52
    -                .expireAfterWrite(expireDelay, TimeUnit.MINUTES)
    
    53 56
                     .expireAfterAccess(expireDelay, TimeUnit.MINUTES)
    
    54
    -                .removalListener((RemovalListener<String, ObserveWebUserSession>) notification -> log.info(String.format("Remove session: %s - %s", notification.getKey(), notification.getValue())))
    
    57
    +                .removalListener((RemovalListener<String, ObserveWebUserSession>) notification -> sessionRemoved(notification.getKey()))
    
    55 58
                     .build();
    
    56 59
         }
    
    57 60
     
    
    58
    -    public ObserveWebUserSession getSessionIfPresent(String authenticationToken) {
    
    59
    -        return sessionCache.getIfPresent(authenticationToken);
    
    61
    +    public ObserveWebUserSession getSession(Locale locale, String authenticationToken, DataSourceApiAccess requestApiAccess) {
    
    62
    +        ObserveWebUserSession session = sessionCache.getIfPresent(authenticationToken);
    
    63
    +        if (session == null) {
    
    64
    +            throw new InvalidAuthenticationTokenException(locale, authenticationToken);
    
    65
    +        }
    
    66
    +        if (session.rejectApiAccess(requestApiAccess)) {
    
    67
    +            throw new InvalidApiAccessException(locale, requestApiAccess, session.getUserPermission().getApiAccess());
    
    68
    +        }
    
    69
    +        return session;
    
    70
    +
    
    60 71
         }
    
    61 72
     
    
    62 73
         public void registerSession(ObserveWebUserSession session) {
    
    63
    -        String sessionId = session.getAuthenticationToken();
    
    64
    -        log.info(String.format("Add session: %s for data source configuration: %s", sessionId, session.getConfiguration()));
    
    65
    -        sessionCache.put(sessionId, session);
    
    74
    +        String authenticationToken = session.getAuthenticationToken();
    
    75
    +        log.info(String.format("Add session: %s for data source configuration: %s", authenticationToken, session.getConfiguration()));
    
    76
    +        sessionCache.put(authenticationToken, session);
    
    66 77
         }
    
    67 78
     
    
    68
    -    public void removeSession(String sessionId) {
    
    69
    -        log.info(String.format("Remove session: %s ", sessionId));
    
    70
    -        sessionCache.invalidate(sessionId);
    
    79
    +    public void removeSession(String authenticationToken) {
    
    80
    +        log.info(String.format("Will remove session: %s ", authenticationToken));
    
    81
    +        sessionCache.invalidate(authenticationToken);
    
    82
    +        sessionRemoved(authenticationToken);
    
    71 83
         }
    
    72 84
     
    
    73
    -    public void removeAllSessions() {
    
    74
    -        log.info("Remove all session");
    
    75
    -        sessionCache.invalidateAll();
    
    85
    +    public void sessionRemoved(String authenticationToken) {
    
    86
    +        log.info(String.format("Session removed: %s ", authenticationToken));
    
    76 87
         }
    
    77 88
     
    
    78 89
         public Cache<String, ObserveWebUserSession> getSessionCache() {
    
    ... ... @@ -81,7 +92,8 @@ public class ObserveWebSecuritySessionCache implements Closeable {
    81 92
     
    
    82 93
         @Override
    
    83 94
         public void close() {
    
    84
    -        removeAllSessions();
    
    95
    +        log.info("Remove all session");
    
    96
    +        sessionCache.invalidateAll();
    
    85 97
         }
    
    86 98
     
    
    87 99
     }

  • server/core/src/main/java/fr/ird/observe/server/security/ObserveWebUserSession.java
    ... ... @@ -186,7 +186,7 @@ public class ObserveWebUserSession implements ObserveDataSourceConfigurationAndC
    186 186
             return new ObserveWebRequestContext(applicationContext, this, serviceInitializerConfig);
    
    187 187
         }
    
    188 188
     
    
    189
    -    public ObserveWebUserSession toConfigurationSession(ObserveWebSecurityConfigCacheKey configCacheKey) {
    
    189
    +    public ObserveWebUserSession toConfigurationSession(ObserveWebSecurityConfigCacheValue configCacheKey) {
    
    190 190
             return new ObserveWebUserSession(this, configCacheKey.getConfiguration(), configCacheKey.getServerUser(), configCacheKey.getServerUserPermission());
    
    191 191
         }
    
    192 192
     
    

  • server/runner/README.md
    1
    -To deploy new version of pom: mvn deploy
    
    2
    -To install localy: mvn install
    1
    +Welcome to Observe server
    
    2
    +
    
    3
    +## Init root directory
    
    4
    +
    
    5
    +By default, server use a special directory to store all his data: ```/var/local/observe-server```
    
    6
    +
    
    7
    +The user that run the tomcat instance must be able to read and write in this directory.
    
    8
    +
    
    9
    +Please apply the following command with root user, before starting the first instance of v9.
    
    10
    +
    
    11
    +```sh
    
    12
    +mkdir -p /var/local/observe-server
    
    13
    +chown -R tomcat:staff /var/local/observe-server
    
    14
    +```
    
    15
    +
    
    16
    +TODO Write a nice document for any help with the server

  • server/runner/src/main/assembly/server.xml
    ... ... @@ -32,7 +32,7 @@
    32 32
           </includes>
    
    33 33
         </fileSet>
    
    34 34
         <fileSet>
    
    35
    -      <directory>src/main/resources</directory>
    
    35
    +      <directory>src/main/resources/META-INF/configuration</directory>
    
    36 36
           <outputDirectory>config</outputDirectory>
    
    37 37
           <includes>
    
    38 38
             <include>log.xml</include>
    
    ... ... @@ -53,6 +53,14 @@
    53 53
             <include>${applicationName}-${project.version}.war</include>
    
    54 54
           </includes>
    
    55 55
         </fileSet>
    
    56
    +    <fileSet>
    
    57
    +      <directory/>
    
    58
    +      <outputDirectory/>
    
    59
    +      <fileMode>0755</fileMode>
    
    60
    +      <includes>
    
    61
    +        <include>README.md</include>
    
    62
    +      </includes>
    
    63
    +    </fileSet>
    
    56 64
         <fileSet>
    
    57 65
           <directory>target/classes</directory>
    
    58 66
           <outputDirectory/>
    

  • server/runner/src/main/i18n/translations/server-runner_fr_FR.properties
    1 1
     server.config.name=Observe web Configuration
    
    2 2
     server.config.option.common.directory.config=Répertoire des configurations partagées
    
    3
    -server.config.option.common.directory.config.file=Chemin vers le fichier commun de configuration
    
    3
    +server.config.option.common.directory.config.file=Chemin vers le fichier commun de configuration de l'application
    
    4 4
     server.config.option.common.directory.config.file.log=Chemin vers le fichier commun de configuration des logs
    
    5 5
     server.config.option.common.directory.config.file.server=Chemin vers le fichier commun de configuration des bases
    
    6 6
     server.config.option.common.directory.instances=Chemin des instances
    
    ... ... @@ -16,5 +16,5 @@ server.config.option.instance.locale.referential=La langue du référentiel (fr_
    16 16
     server.config.option.instance.security.key=Clé API Admin (À changer)
    
    17 17
     server.config.option.instance.session.maximum.size=Taille maximum de session
    
    18 18
     server.config.option.instance.timeout.http=Temps maximum de tentative de connection http (en millisecondes)
    
    19
    -server.config.option.instance.timeout.session=Temps maximum d'une session (en minutes)
    
    19
    +server.config.option.instance.timeout.session=Durée de vie d'un jeton d'authentification (en minutes)
    
    20 20
     server.config.option.instance.timeout.temporary.files=Nettoyage des fichiers temporaires (en heures)

  • server/runner/src/main/resources/log.xmlserver/runner/src/main/resources/META-INF/configuration/log.xml