diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java b/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java index 474cc6f3..49dc5ef8 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/AAChannelProcessor.java @@ -7,6 +7,7 @@ import org.phoebus.channelfinder.processors.ChannelProcessor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.Arrays; @@ -51,6 +52,7 @@ public class AAChannelProcessor implements ChannelProcessor { @Value("${aa.auto_pause:}") private List autoPauseOptions; + @Autowired private final ArchiverClient archiverClient = new ArchiverClient(); @Override @@ -195,24 +197,16 @@ private Map> getArchiveActions( if (archivePVS.isEmpty()) { return result; } - - try { - List> statuses = archiverClient.getStatuses(archivePVS, archiverInfo.url(), archiverInfo.version()); - statuses - .forEach(archivePVStatusJsonMap -> { - String archiveStatus = archivePVStatusJsonMap.get("status"); - String pvName = archivePVStatusJsonMap.get("pvName"); - String pvStatus = archivePVS.get(pvName).getPvStatus(); - ArchiveAction action = pickArchiveAction(archiveStatus, pvStatus); - result.get(action).add(archivePVS.get(pvName)); - }); - return result; - - } catch (JsonProcessingException e) { - // problem collecting policies from AA, so warn and return empty list - logger.log(Level.WARNING, () -> "Could not get AA pv Status list: " + e.getMessage()); - return result; - } + List> statuses = archiverClient.getStatuses(archivePVS, archiverInfo.url(), archiverInfo.alias()); + statuses + .forEach(archivePVStatusJsonMap -> { + String archiveStatus = archivePVStatusJsonMap.get("status"); + String pvName = archivePVStatusJsonMap.get("pvName"); + String pvStatus = archivePVS.get(pvName).getPvStatus(); + ArchiveAction action = pickArchiveAction(archiveStatus, pvStatus); + result.get(action).add(archivePVS.get(pvName)); + }); + return result; } private ArchivePVOptions createArchivePV( diff --git a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java index 94134d31..da4ebd68 100644 --- a/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java +++ b/src/main/java/org/phoebus/channelfinder/processors/aa/ArchiverClient.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.beans.factory.annotation.Value; import reactor.core.publisher.Mono; import java.net.URI; @@ -27,26 +28,6 @@ public class ArchiverClient { private static final Logger logger = Logger.getLogger(ArchiverClient.class.getName()); private static final int STATUS_BATCH_SIZE = 100; // Limit comes from tomcat server maxHttpHeaderSize which by default is a header of size 8k - private static final List AA_STATUS_ENDPOINT_ONLY_SUPPORT_QUERY_VERSION = List.of("1.1.0", - "Before_JDK_12_Upgrade", - "v0.0.1_SNAPSHOT_03-November-2015", - "v0.0.1_SNAPSHOT_09-Oct-2018", - "v0.0.1_SNAPSHOT_10-June-2017", - "v0.0.1_SNAPSHOT_10-Sep-2015", - "v0.0.1_SNAPSHOT_12-May-2016", - "v0.0.1_SNAPSHOT_12-Oct-2016", - "v0.0.1_SNAPSHOT_13-Nov-2019", - "v0.0.1_SNAPSHOT_14-Jun-2018", - "v0.0.1_SNAPSHOT_15-Nov-2018", - "v0.0.1_SNAPSHOT_20-Sept-2016", - "v0.0.1_SNAPSHOT_22-June-2016", - "v0.0.1_SNAPSHOT_22-June-2017", - "v0.0.1_SNAPSHOT_23-Sep-2015", - "v0.0.1_SNAPSHOT_26-January-2016", - "v0.0.1_SNAPSHOT_27-Nov-2017", - "v0.0.1_SNAPSHOT_29-July-2015", - "v0.0.1_SNAPSHOT_30-March-2016", - "v0.0.1_SNAPSHOT_30-September-2021"); private final WebClient client = WebClient.create(); @@ -55,7 +36,11 @@ public class ArchiverClient { private static final String PV_STATUS_RESOURCE = MGMT_RESOURCE + "/getPVStatus"; private static final String ARCHIVER_VERSIONS_RESOURCE = MGMT_RESOURCE + "/getVersions"; private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final int TIMEOUT_SECONDS = 15; + + @Value("${aa.timeout_seconds:15}") + private int timeoutSeconds; + @Value("${aa.post_support:}") + private List postSupportArchivers; private Stream> partitionSet(Set pvSet, int pageSize) { List list = new ArrayList<>(pvSet); @@ -63,15 +48,20 @@ private Stream> partitionSet(Set pvSet, int pageSize) { .mapToObj(i -> list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size()))); } - List> getStatuses(Map archivePVS, String archiverURL, String archiverVersion) throws JsonProcessingException { + List> getStatuses(Map archivePVS, String archiverURL, String archiverAlias) { Set pvs = archivePVS.keySet(); - if (AA_STATUS_ENDPOINT_ONLY_SUPPORT_QUERY_VERSION.contains(archiverVersion)) { - + Boolean postSupportOverride = postSupportArchivers.contains(archiverAlias); + logger.log(Level.INFO, "Archiver Alias: {0}", archiverAlias); + logger.log(Level.INFO, "Post Support Override Archivers: {0}", postSupportArchivers); + + if (Boolean.TRUE.equals(postSupportOverride)) { + logger.log(Level.INFO, "Post Support"); + return getStatusesFromPvListBody(archiverURL, pvs.stream().toList()); + } else { + logger.log(Level.INFO, "Query Support"); Stream> stream = partitionSet(pvs, STATUS_BATCH_SIZE); return stream.map(pvList -> getStatusesFromPvListQuery(archiverURL, pvList)).flatMap(List::stream).toList(); - } else { - return getStatusesFromPvListBody(archiverURL, pvs.stream().toList()); } } @@ -86,7 +76,7 @@ private List> getStatusesFromPvListQuery(String archiverURL, .uri(pvStatusURI) .retrieve() .bodyToMono(String.class) - .timeout(Duration.of(TIMEOUT_SECONDS, ChronoUnit.SECONDS)) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) .onErrorResume(e -> showError(uriString, e)) .block(); @@ -110,7 +100,7 @@ private List> getStatusesFromPvListBody(String archiverURL, .bodyValue(pvs) .retrieve() .bodyToMono(String.class) - .timeout(Duration.of(TIMEOUT_SECONDS, ChronoUnit.SECONDS)) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) .onErrorResume(e -> showError(uriString, e)) .block(); @@ -125,7 +115,7 @@ private List> getStatusesFromPvListBody(String archiverURL, } catch (JsonProcessingException e) { logger.log(Level.WARNING, "Could not parse pv status response: " + e.getMessage()); } catch (Exception e) { - logger.log(Level.WARNING, String.format("Error when trying to get status from pv list query: %s", e.getMessage())); + logger.log(Level.WARNING, String.format("Error when trying to get status from pv list body: %s", e.getMessage())); } return List.of(); } @@ -139,7 +129,7 @@ private void submitAction(String values, String endpoint, String aaURL) { .bodyValue(values) .retrieve() .bodyToMono(String.class) - .timeout(Duration.of(TIMEOUT_SECONDS, ChronoUnit.SECONDS)) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) .onErrorResume(e -> showError(uriString, e)) .block(); logger.log(Level.FINE, () -> response); @@ -227,7 +217,7 @@ String getVersion(String archiverURL) { .uri(URI.create(uriString)) .retrieve() .bodyToMono(String.class) - .timeout(Duration.of(TIMEOUT_SECONDS, ChronoUnit.SECONDS)) + .timeout(Duration.of(timeoutSeconds, ChronoUnit.SECONDS)) .onErrorResume(e -> showError(uriString, e)) .block(); Map versionMap = objectMapper.readValue(response, Map.class); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2ac4361e..6e23bb1b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -122,6 +122,10 @@ aa.enabled=true aa.pva=false aa.archive_property_name=archive aa.archiver_property_name=archiver +aa.timeout_seconds=15 + +# Comma-separated list of archivers to use post support +aa.post_support= # Set the auto pause behaviour # diff --git a/src/site/sphinx/aa_processor.rst b/src/site/sphinx/aa_processor.rst index c8edff04..5725685b 100644 --- a/src/site/sphinx/aa_processor.rst +++ b/src/site/sphinx/aa_processor.rst @@ -11,6 +11,11 @@ A list of archiver appliance URLs and aliases. :: aa.urls={'default': 'http://archiver-01.example.com:17665', 'neutron-controls': 'http://archiver-02.example.com:17665'} +By default the listed archivers will get statuses by pv query. +To set the archivers to use get statuses by pv list body, set the property :ref:`aa.post_support` to a comma separated list of archiver aliases. :: + + aa.post_support=default, neutron-controls + To set the choice of default archiver appliance, set the property :ref:`aa.default_alias` to the alias of the default archiver appliance. This setting can also be a comma-separated list if you want multiple default archivers. To pass the PV as "pva://PVNAME" to the archiver appliance, set the property :ref:`aa.pva` to **true**. diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java new file mode 100644 index 00000000..d26910c5 --- /dev/null +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiArchiverIT.java @@ -0,0 +1,265 @@ +package org.phoebus.channelfinder.processors; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.phoebus.channelfinder.entity.Channel; +import org.phoebus.channelfinder.processors.aa.AAChannelProcessor; +import org.phoebus.channelfinder.processors.aa.ArchiveAction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.TestPropertySource; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.activeProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.archiveProperty; +import static org.phoebus.channelfinder.processors.AAChannelProcessorIT.inactiveProperty; + +@WebMvcTest(AAChannelProcessor.class) +@TestPropertySource(value = "classpath:application_test_multi.properties") +class AAChannelProcessorMultiArchiverIT { + + public static final String BEING_ARCHIVED = "Being archived"; + public static final String PAUSED = "Paused"; + public static final String NOT_BEING_ARCHIVED = "Not being archived"; + public static final String OWNER = "owner"; + @Autowired + AAChannelProcessor aaChannelProcessor; + + MockWebServer mockQueryArchiverAppliance; + MockWebServer mockPostArchiverAppliance; + ObjectMapper objectMapper; + + @BeforeEach + void setUp() throws IOException { + mockQueryArchiverAppliance = new MockWebServer(); + mockQueryArchiverAppliance.start(17664); + mockPostArchiverAppliance = new MockWebServer(); + mockPostArchiverAppliance.start(17665); + + objectMapper = new ObjectMapper(); + } + + @AfterEach + void teardown() throws IOException { + mockQueryArchiverAppliance.shutdown(); + mockPostArchiverAppliance.shutdown(); + } + + static Stream provideArguments() { + List channels = List.of( + new Channel("PVArchivedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel("PVPausedActive", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel("PVNoneActive0", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel("PVArchivedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel("PVPausedInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel("PVNoneInactive", OWNER, List.of(archiveProperty, inactiveProperty), List.of()), + new Channel("PVArchivedNotag", OWNER, List.of(), List.of()), + new Channel("PVNoneActive1", OWNER, List.of(archiveProperty, activeProperty), List.of()), + new Channel("PVNoneActive2", OWNER, List.of(archiveProperty, activeProperty), List.of()) + ); + + Map namesToStatuses = Map.of( + "PVArchivedActive", BEING_ARCHIVED, + "PVPausedActive", PAUSED, + "PVNoneActive0", NOT_BEING_ARCHIVED, + "PVArchivedInactive", BEING_ARCHIVED, + "PVPausedInactive", PAUSED, + "PVNoneInactive", NOT_BEING_ARCHIVED, + "PVArchivedNotag", BEING_ARCHIVED, + "PVNoneActive1", NOT_BEING_ARCHIVED, + "PVNoneActive2", NOT_BEING_ARCHIVED + ); + Map> actionsToNames = Map.of( + ArchiveAction.RESUME, List.of("PVPausedActive"), + ArchiveAction.PAUSE, List.of("PVArchivedInactive", "PVArchivedNotag"), + ArchiveAction.ARCHIVE, List.of("PVNoneActive0", "PVNoneActive1", "PVNoneActive2") + ); + int expectedProcessedChannels = 12; + + List massPVNames = IntStream.range(1, 100).mapToObj(i -> "PV" + i).toList(); + return Stream.of( + Arguments.of(channels, namesToStatuses, actionsToNames, expectedProcessedChannels), + Arguments.of( + massPVNames.stream().map(s -> new Channel(s, OWNER, List.of(archiveProperty, activeProperty), List.of())).toList(), + massPVNames.stream().collect(Collectors.toMap(String::toString, e -> NOT_BEING_ARCHIVED)), + Map.of(ArchiveAction.ARCHIVE, massPVNames), + massPVNames.size() + )); + } + + @ParameterizedTest + @MethodSource("provideArguments") + void testProcessMultiArchivers(List channels, + Map namesToStatuses, + Map> actionsToNames, + int expectedProcessedChannels) + throws JsonProcessingException, InterruptedException { + + // Request to version + Map queryVersions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Query Support"); + mockQueryArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(queryVersions)) + .addHeader("Content-Type", "application/json")); + + // Request to policies + Map policyList = Map.of("policy", "description"); + mockQueryArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(policyList)) + .addHeader("Content-Type", "application/json")); + + // Request to archiver status + List> archivePVStatuses = + namesToStatuses.entrySet().stream().map(entry -> Map.of("pvName", entry.getKey(), "status", entry.getValue())).toList(); + mockQueryArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(archivePVStatuses)) + .addHeader("Content-Type", "application/json")); + + // Requests to archiver + actionsToNames.forEach((key, value) -> { + List> archiverResponse = + value.stream().map(channel -> Map.of("pvName", channel, "status", key + " request submitted")).toList(); + try { + mockQueryArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(archiverResponse)) + .addHeader("Content-Type", "application/json")); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + }); + + + // Request to query version + Map postVersions = Map.of("mgmt_version", "Archiver Appliance Version 1.1.0 Post Support"); + mockPostArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(postVersions)) + .addHeader("Content-Type", "application/json")); + + // Request to policies + mockPostArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(policyList)) + .addHeader("Content-Type", "application/json")); + + // Request to archiver status + mockPostArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(archivePVStatuses)) + .addHeader("Content-Type", "application/json")); + + // Requests to archiver + actionsToNames.forEach((key, value) -> { + List> archiverResponse = + value.stream().map(channel -> Map.of("pvName", channel, "status", key + " request submitted")).toList(); + try { + mockPostArchiverAppliance.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(archiverResponse)) + .addHeader("Content-Type", "application/json")); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + }); + + aaChannelProcessor.process(channels); + + AtomicInteger expectedQueryRequests = new AtomicInteger(1); + RecordedRequest requestQueryVersion = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestQueryVersion.getPath()); + + expectedQueryRequests.addAndGet(1); + RecordedRequest requestQueryPolicy = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestQueryPolicy.getPath()); + + expectedQueryRequests.addAndGet(1); + RecordedRequest requestQueryStatus = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestQueryStatus != null; + assert requestQueryStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestQueryStatus.getRequestUrl().encodedPath()); + + AtomicInteger expectedPostRequests = new AtomicInteger(1); + RecordedRequest requestPostVersion = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostVersion != null; + assertEquals("/mgmt/bpl/getVersions", requestPostVersion.getPath()); + + expectedPostRequests.addAndGet(1); + RecordedRequest requestPostPolicy = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostPolicy != null; + assertEquals("/mgmt/bpl/getPolicyList", requestPostPolicy.getPath()); + + expectedPostRequests.addAndGet(1); + RecordedRequest requestPostStatus = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + assert requestPostStatus != null; + assert requestPostStatus.getRequestUrl() != null; + assertEquals("/mgmt/bpl/getPVStatus", requestPostStatus.getRequestUrl().encodedPath()); + + while (mockQueryArchiverAppliance.getRequestCount() > 0) { + RecordedRequest requestAction = null; + try { + requestAction = mockQueryArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (requestAction == null) { + break; + } + expectedQueryRequests.addAndGet(1); + assert requestAction.getPath() != null; + assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); + ArchiveAction key = actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); + String body = requestAction.getBody().readUtf8(); + actionsToNames.get(key).forEach(pv -> + assertTrue(body.contains(pv)) + ); + } + + while (mockPostArchiverAppliance.getRequestCount() > 0) { + RecordedRequest requestAction = null; + try { + requestAction = mockPostArchiverAppliance.takeRequest(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (requestAction == null) { + break; + } + expectedPostRequests.addAndGet(1); + assert requestAction.getPath() != null; + assertTrue(requestAction.getPath().startsWith("/mgmt/bpl")); + ArchiveAction key = actionFromEndpoint(requestAction.getPath().substring("/mgmt/bpl".length())); + String body = requestAction.getBody().readUtf8(); + actionsToNames.get(key).forEach(pv -> + assertTrue(body.contains(pv)) + ); + } + + assertEquals(mockPostArchiverAppliance.getRequestCount(), expectedPostRequests.get()); + assertEquals(mockQueryArchiverAppliance.getRequestCount(), expectedQueryRequests.get()); + } + + + public ArchiveAction actionFromEndpoint(final String endpoint) { + for (ArchiveAction action : ArchiveAction.values()) { + if (action.getEndpoint().equals(endpoint)) { + return action; + } + } + return null; + } +} diff --git a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java index 32ae1387..9c63f159 100644 --- a/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java +++ b/src/test/java/org/phoebus/channelfinder/processors/AAChannelProcessorMultiIT.java @@ -7,7 +7,6 @@ import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -19,10 +18,8 @@ import org.springframework.test.context.TestPropertySource; import java.io.IOException; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; diff --git a/src/test/resources/application_test_multi.properties b/src/test/resources/application_test_multi.properties new file mode 100644 index 00000000..5f1b28d4 --- /dev/null +++ b/src/test/resources/application_test_multi.properties @@ -0,0 +1,111 @@ +################## ChannelFinder Server #################### +server.port=8443 + +# Options support for unsecure http +server.http.enable=true +server.http.port=8080 + +server.ssl.key-store-type=PKCS12 +server.ssl.key-store=classpath:keystore/cf.p12 +server.ssl.key-store-password=password +server.ssl.key-alias=cf + +security.require-ssl=true + +server.compression.enabled=true +# opt in to content types +server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css +# not worth the CPU cycles at some point, probably +server.compression.min-response-size=1024 +# Enable HTTP/2 support, if the current environment supports it +server.http2.enabled=true +logging.level.org.springframework.web=INFO + +############## LDAP - External ############## +ldap.enabled = false +#ldap.urls = ldaps://controlns02.nsls2.bnl.gov/dc=nsls2,dc=bnl,dc=gov +ldap.base.dn = dc=nsls2,dc=bnl,dc=gov +ldap.user.dn.pattern = uid={0},ou=People +ldap.groups.search.base = ou=Group +ldap.groups.search.pattern = (memberUid= {1}) + +############## LDAP - Embedded ############## +embedded_ldap.enabled = false +embedded_ldap.urls = ldap://localhost:8389/dc=olog,dc=local +embedded_ldap.base.dn = dc=olog,dc=local +embedded_ldap.user.dn.pattern = uid={0},ou=People +embedded_ldap.groups.search.base = ou=Group +embedded_ldap.groups.search.pattern = (memberUid= {1}) +spring.ldap.embedded.ldif=classpath:cf.ldif +spring.ldap.embedded.base-dn=dc=cf,dc=local +spring.ldap.embedded.port=8389 +spring.ldap.embedded.validation.enabled=false + + +############## Demo Auth ############## +# users, pwds, roles - lists of comma-separated values (same length) +# roles may contain multiple roles for user separated by delimiter +# e.g. +# demo_auth.users = user1,user2 +# demo_auth.pwds = pwd1,pwd2 +# demo_auth.roles = role1,role2 +# demo_auth.roles = role1,role21:role22 +demo_auth.enabled = true + +############## Group-->Role Mapping ############## +# Customize group names here +admin-groups=cf-admins,sys-admins +channel-groups=cf-channels +property-groups=cf-properties +tag-groups=cf-tags + +############################## Elastic Network And HTTP ############################### + +# Comma-separated list of URLs for the Elasticsearch hosts. All hosts listed +# here must belong to the same Elasticsearch cluster. +elasticsearch.host_urls=http://localhost:9200 + +# Elasticsearch index names and types used by channelfinder, ensure that any changes here should be replicated in the mapping_definitions.sh +elasticsearch.tag.index = test_${random.int[1,1000]}_cf_tags +elasticsearch.property.index = test_${random.int[1,1000]}_cf_properties +elasticsearch.channel.index = test_${random.int[1,1000]}_channelfinder + +# maximum query result size +# WARNING this changes the elastic settings. UPDATE with care. +elasticsearch.query.size = 10000 + +# Create the Channel Finder indices if they do not exist +elasticsearch.create.indices = true + +############################## Service Info ############################### +# ChannelFinder version as defined in the pom file +channelfinder.version=@project.version@ + +############################## REST Logging ############################### +# DEBUG level will log all requests and responses to and from the REST end points +logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=INFO + +################ Archiver Appliance Configuration Processor ################# +aa.urls={'post': 'http://localhost:17664', 'query': 'http://localhost:17665'} +aa.default_alias=post, query +aa.enabled=true +aa.pva=false +aa.archive_property_name=archive +aa.archiver_property_name=archiver +aa.post_support=post + +# Set the auto pause behaviour +# +# Empty for no auto pause +# Or pvStatus to pause on pvStatus=Inactive +# Or match archive_property_name to pause on archive_property_name not existing +# Or both, i.e. aa.auto_pause=pvStatus,archive +# +aa.auto_pause=pvStatus,archive + + +############################## Metrics ############################### +#actuator +management.endpoints.web.exposure.include=prometheus, metrics, health, info +metrics.tags=group4_10 +metrics.properties=group4: 10; group5: 10 \ No newline at end of file