summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java62
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java20
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java52
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java33
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java35
-rw-r--r--config-model/src/main/resources/schema/containercluster.rnc8
-rw-r--r--config-model/src/main/resources/schema/deployment.rnc9
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java28
-rw-r--r--config-model/src/test/schema-test-files/deployment.xml4
-rw-r--r--config-model/src/test/schema-test-files/services.xml4
10 files changed, 188 insertions, 67 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
index 4d370ba5039..1a2335c82db 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
@@ -39,28 +39,36 @@ public class DeploymentSpec {
UpgradePolicy.defaultPolicy,
Collections.emptyList(),
Collections.emptyList(),
- "<deployment version='1.0'/>");
+ "<deployment version='1.0'/>",
+ Optional.empty(),
+ Optional.empty());
private final Optional<String> globalServiceId;
private final UpgradePolicy upgradePolicy;
private final List<ChangeBlocker> changeBlockers;
private final List<Step> steps;
private final String xmlForm;
+ private final Optional<String> athenzDomain;
+ private final Optional<String> athenzService;
public DeploymentSpec(Optional<String> globalServiceId, UpgradePolicy upgradePolicy,
List<ChangeBlocker> changeBlockers, List<Step> steps) {
- this(globalServiceId, upgradePolicy, changeBlockers, steps, null);
+ this(globalServiceId, upgradePolicy, changeBlockers, steps, null, Optional.empty(), Optional.empty());
}
public DeploymentSpec(Optional<String> globalServiceId, UpgradePolicy upgradePolicy,
- List<ChangeBlocker> changeBlockers, List<Step> steps, String xmlForm) {
+ List<ChangeBlocker> changeBlockers, List<Step> steps, String xmlForm,
+ Optional<String> athenzDomain, Optional<String> athenzService) {
validateTotalDelay(steps);
this.globalServiceId = globalServiceId;
this.upgradePolicy = upgradePolicy;
this.changeBlockers = changeBlockers;
this.steps = ImmutableList.copyOf(completeSteps(new ArrayList<>(steps)));
this.xmlForm = xmlForm;
+ this.athenzDomain = athenzDomain;
+ this.athenzService = athenzService;
validateZones(this.steps);
+ validateAthenz();
}
/** Throw an IllegalArgumentException if the total delay exceeds 24 hours */
@@ -81,7 +89,30 @@ public class DeploymentSpec {
for (DeclaredZone zone : step.zones())
ensureUnique(zone, zones);
}
-
+
+ /*
+ * Throw an IllegalArgumentException if Athenz configuration violates:
+ * domain not configured -> no zone can configure service
+ * domain configured -> all zones must configure service
+ */
+ private void validateAthenz() {
+ // If athenz domain is not set, athenz service cannot be set on any level
+ if (! athenzDomain.isPresent()) {
+ for (DeclaredZone zone : zones()) {
+ if(zone.athenzService().isPresent()) {
+ throw new IllegalArgumentException("Athenz service configured for zone: " + zone + ", but Athenz domain is not configured");
+ }
+ }
+ // if athenz domain is configured, athenz service must be set implicitly or directly on all zones.
+ } else if(! athenzService.isPresent()) {
+ for (DeclaredZone zone : zones()) {
+ if(! zone.athenzService().isPresent()) {
+ throw new IllegalArgumentException("Athenz domain is configured, but Athenz service not configured for zone: " + zone);
+ }
+ }
+ }
+ }
+
private void ensureUnique(DeclaredZone zone, Set<DeclaredZone> zones) {
if ( ! zones.add(zone))
throw new IllegalArgumentException(zone + " is listed twice in deployment.xml");
@@ -212,6 +243,20 @@ public class DeploymentSpec {
return b.toString();
}
+ /** Returns the athenz domain if configured */
+ public Optional<String> athenzDomain() {
+ return athenzDomain;
+ }
+
+ /** Returns the athenz service for environment/region if configured */
+ public Optional<String> athenzService(Environment environment, RegionName region) {
+ return zones().stream()
+ .filter(zone -> zone.deploysTo(environment, Optional.of(region)))
+ .findFirst()
+ .map(DeclaredZone::athenzService)
+ .orElse(athenzService);
+ }
+
/** This may be invoked by a continuous build */
public static void main(String[] args) {
if (args.length != 2 && args.length != 3) {
@@ -276,11 +321,17 @@ public class DeploymentSpec {
private final boolean active;
+ private Optional<String> athenzService;
+
public DeclaredZone(Environment environment) {
this(environment, Optional.empty(), false);
}
public DeclaredZone(Environment environment, Optional<RegionName> region, boolean active) {
+ this(environment, region, active, Optional.empty());
+ }
+
+ public DeclaredZone(Environment environment, Optional<RegionName> region, boolean active, Optional<String> athenzService) {
if (environment != Environment.prod && region.isPresent())
throw new IllegalArgumentException("Non-prod environments cannot specify a region");
if (environment == Environment.prod && ! region.isPresent())
@@ -288,6 +339,7 @@ public class DeploymentSpec {
this.environment = environment;
this.region = region;
this.active = active;
+ this.athenzService = athenzService;
}
public Environment environment() { return environment; }
@@ -298,6 +350,8 @@ public class DeploymentSpec {
/** Returns whether this zone should receive production traffic */
public boolean active() { return active; }
+ public Optional<String> athenzService() { return athenzService; }
+
@Override
public List<DeclaredZone> zones() { return Collections.singletonList(this); }
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
index 5599b257b16..1a970e53713 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
@@ -72,6 +72,7 @@ public class DeploymentSpecXmlReader {
if (environment == Environment.prod) {
for (Element stepTag : XML.getChildren(environmentTag)) {
+ Optional<String> athenzService = stringAttribute("athenz-service", environmentTag);
if (stepTag.getTagName().equals("delay")) {
steps.add(new Delay(Duration.ofSeconds(longAttribute("hours", stepTag) * 60 * 60 +
longAttribute("minutes", stepTag) * 60 +
@@ -79,11 +80,11 @@ public class DeploymentSpecXmlReader {
} else if (stepTag.getTagName().equals("parallel")) {
List<DeclaredZone> zones = new ArrayList<>();
for (Element regionTag : XML.getChildren(stepTag)) {
- zones.add(readDeclaredZone(environment, regionTag));
+ zones.add(readDeclaredZone(environment, athenzService, regionTag));
}
steps.add(new ParallelZones(zones));
} else { // a region: deploy step
- steps.add(readDeclaredZone(environment, stepTag));
+ steps.add(readDeclaredZone(environment, athenzService, stepTag));
}
}
} else {
@@ -94,8 +95,11 @@ public class DeploymentSpecXmlReader {
globalServiceId = readGlobalServiceId(environmentTag);
else if (readGlobalServiceId(environmentTag).isPresent())
throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag.");
+
}
- return new DeploymentSpec(globalServiceId, readUpgradePolicy(root), readChangeBlockers(root), steps, xmlForm);
+ Optional<String> athenzDomain = stringAttribute("athenz-domain", root);
+ Optional<String> athenzService = stringAttribute("athenz-service", root);
+ return new DeploymentSpec(globalServiceId, readUpgradePolicy(root), readChangeBlockers(root), steps, xmlForm, athenzDomain, athenzService);
}
/** Imposes some constraints on tag order which are not expressible in the schema */
@@ -132,13 +136,19 @@ public class DeploymentSpecXmlReader {
}
}
+ /** Returns the given attribute as a string, or Optional.empty if it is not present or empty */
+ private Optional<String> stringAttribute(String attributeName, Element tag) {
+ String value = tag.getAttribute(attributeName);
+ return Optional.ofNullable(value).filter(s -> ! s.equals(""));
+ }
+
private boolean isEnvironmentName(String tagName) {
return tagName.equals(testTag) || tagName.equals(stagingTag) || tagName.equals(prodTag);
}
- private DeclaredZone readDeclaredZone(Environment environment, Element regionTag) {
+ private DeclaredZone readDeclaredZone(Environment environment, Optional<String> athenzService, Element regionTag) {
return new DeclaredZone(environment, Optional.of(RegionName.from(XML.getValue(regionTag).trim())),
- readActive(regionTag));
+ readActive(regionTag), athenzService);
}
private Optional<String> readGlobalServiceId(Element environmentTag) {
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
index 5050f88af31..5dcb3bc1ebe 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
@@ -367,4 +367,56 @@ public class DeploymentSpecTest {
assertTrue(spec.canUpgradeAt(Instant.parse("2017-09-23T10:15:30.00Z")));
}
+ @Test
+ public void deploymentSpecWithAthenzIdentity() {
+ StringReader r = new StringReader(
+ "<deployment athenz-domain='domain' athenz-service='service'>\n" +
+ " <prod>\n" +
+ " <region active='true'>us-west-1</region>\n" +
+ " </prod>\n" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ assertEquals(spec.athenzDomain().get(), "domain");
+ assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "service");
+ }
+
+ @Test
+ public void deploymentSpecUsesServiceFromEnvironment() {
+ StringReader r = new StringReader(
+ "<deployment athenz-domain='domain' athenz-service='service'>\n" +
+ " <test/>\n" +
+ " <prod athenz-service='prod-service'>\n" +
+ " <region active='true'>us-west-1</region>\n" +
+ " </prod>\n" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ assertEquals(spec.athenzDomain().get(), "domain");
+ assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "prodservice");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void athenzDomainMissingService() {
+ StringReader r = new StringReader(
+ "<deployment athenz-domain='domain'>\n" +
+ " <prod>\n" +
+ " <region active='true'>us-west-1</region>\n" +
+ " </prod>\n" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void athenzDomainMissingDomain() {
+ StringReader r = new StringReader(
+ "<deployment>\n" +
+ " <prod athenz-service='service'>\n" +
+ " <region active='true'>us-west-1</region>\n" +
+ " </prod>\n" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 91d5b7fe267..1e9dc569ff5 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -13,8 +13,10 @@ import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.docproc.DocprocConfig;
import com.yahoo.config.docproc.SchemamappingConfig;
import com.yahoo.config.model.ApplicationConfigProducerRoot;
+import com.yahoo.config.model.api.ConfigServerSpec;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
+import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.Rotation;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.BundlesConfig;
@@ -232,6 +234,7 @@ public final class ContainerCluster
addSimpleComponent("com.yahoo.container.core.slobrok.SlobrokConfigurator");
addSimpleComponent("com.yahoo.container.handler.VipStatus");
addJaxProviders();
+ addIdentity();
}
public void setZone(Zone zone) {
@@ -304,6 +307,36 @@ public final class ContainerCluster
addSimpleComponent(XPathFactoryProvider.class);
}
+ public void addIdentity() {
+ getDeploymentSpec().ifPresent(deploymentSpec -> {
+ deploymentSpec.athenzDomain().ifPresent(domain -> {
+
+ String service = deploymentSpec.athenzService(zone.environment(), zone.region())
+ .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration"));
+
+ Identity identity = new Identity(domain.trim(), service.trim(), getLoadBalancerName());
+ addComponent(identity);
+
+ getContainers().forEach(container -> {
+ container.setProp("identity.domain", domain);
+ container.setProp("identity.service", service);
+ });
+ });
+ });
+ }
+
+ private HostName getLoadBalancerName() {
+ // Set lbaddress, or use first hostname if not specified.
+ // TODO: Remove the orElseGet part when this is set up in all zones
+ return Optional.ofNullable(getRoot().getDeployState().getProperties().loadBalancerName())
+ .orElseGet(
+ () -> HostName.from(getRoot().getDeployState().getProperties().configServerSpecs().stream()
+ .findFirst()
+ .map(ConfigServerSpec::getHostName)
+ .orElse("unknown") // Currently unable to test this, hence the unknown
+ ));
+ }
+
public final void addComponent(Component<?, ?> component) {
if (clusterVerifier.acceptComponent(component)) {
componentGroup.addComponent(component);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index d59846cd5e2..121039a248d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -7,7 +7,6 @@ import com.yahoo.config.application.Xml;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.ConfigModelContext;
-import com.yahoo.config.model.api.ConfigServerSpec;
import com.yahoo.config.model.application.provider.IncludeDirs;
import com.yahoo.config.model.builder.xml.ConfigModelBuilder;
import com.yahoo.config.model.builder.xml.ConfigModelId;
@@ -16,7 +15,6 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.NodeType;
import com.yahoo.container.jdisc.config.MetricDefaultsConfig;
import com.yahoo.search.rendering.RendererRegistry;
@@ -39,7 +37,6 @@ import com.yahoo.vespa.model.clients.ContainerDocumentApi;
import com.yahoo.vespa.model.container.Container;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.ContainerModel;
-import com.yahoo.vespa.model.container.Identity;
import com.yahoo.vespa.model.container.component.Component;
import com.yahoo.vespa.model.container.component.FileStatusHandlerComponent;
import com.yahoo.vespa.model.container.component.chain.ProcessingHandler;
@@ -165,13 +162,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addServerProviders(spec, cluster);
addLegacyFilters(spec, cluster); // TODO: Remove for Vespa 7
- // Athenz copper argos
- // NOTE: Must be done after addNodes()
- addIdentity(spec,
- cluster,
- context.getDeployState().getProperties().configServerSpecs(),
- context.getDeployState().getProperties().loadBalancerName());
-
//TODO: overview handler, see DomQrserverClusterBuilder
}
@@ -698,31 +688,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
}
- private void addIdentity(Element element, ContainerCluster cluster, List<ConfigServerSpec> configServerSpecs, HostName loadBalancerName) {
- Element identityElement = XML.getChild(element, "identity");
- if(identityElement != null) {
- String domain = XML.getValue(XML.getChild(identityElement, "domain"));
- String service = XML.getValue(XML.getChild(identityElement, "service"));
-
- // Set lbaddress, or use first hostname if not specified.
- HostName lbName = Optional.ofNullable(loadBalancerName)
- .orElseGet(
- () -> HostName.from(configServerSpecs.stream()
- .findFirst()
- .map(ConfigServerSpec::getHostName)
- .orElse("unknown") // Currently unable to test this, hence the unknown
- ));
-
- Identity identity = new Identity(domain.trim(), service.trim(), lbName);
- cluster.addComponent(identity);
-
- cluster.getContainers().forEach(container -> {
- container.setProp("identity.domain", domain);
- container.setProp("identity.service", service);
- });
- }
- }
-
/**
* Disallow renderers named "DefaultRenderer" or "JsonRenderer"
*/
diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc
index 47cf0638d72..6a90bef7bb2 100644
--- a/config-model/src/main/resources/schema/containercluster.rnc
+++ b/config-model/src/main/resources/schema/containercluster.rnc
@@ -7,8 +7,7 @@ ContainerCluster = element container | jdisc {
ContainerServices &
DocumentBinding* &
Aliases? &
- NodesOfContainerCluster? &
- Identity?
+ NodesOfContainerCluster?
}
ContainerServices =
@@ -226,8 +225,3 @@ DocumentBinding = element document {
attribute class { xsd:NCName } &
attribute bundle { xsd:NCName }
}
-
-Identity = element identity {
- element domain { xsd:NCName } &
- element service { xsd:NCName }
-}
diff --git a/config-model/src/main/resources/schema/deployment.rnc b/config-model/src/main/resources/schema/deployment.rnc
index 90bff8e31b3..2ecfa781876 100644
--- a/config-model/src/main/resources/schema/deployment.rnc
+++ b/config-model/src/main/resources/schema/deployment.rnc
@@ -4,6 +4,8 @@
start = element deployment {
attribute version { "1.0" } &
+ attribute athenz-domain { xsd:string }? &
+ attribute athenz-service { xsd:string }? &
Upgrade? &
BlockChange* &
Test? &
@@ -31,15 +33,18 @@ BlockUpgrade = element block-upgrade { # Legacy name - remove on Vespa 7
}
Test = element test {
- text
+ attribute athenz-service { xsd:string }? &
+ text
}
Staging = element staging {
- text
+ attribute athenz-service { xsd:string }? &
+ text
}
Prod = element prod {
attribute global-service-id { text }? &
+ attribute athenz-service { xsd:string }? &
Region* &
Delay* &
Parallel*
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java
index df118b0e349..c8a245e68b0 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java
@@ -1,7 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.xml;
+import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.builder.xml.test.DomBuilderTest;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.model.test.MockApplicationPackage;
+import com.yahoo.config.model.test.MockRoot;
import com.yahoo.container.core.identity.IdentityConfig;
import com.yahoo.vespa.model.container.Identity;
import org.junit.Test;
@@ -17,16 +21,24 @@ import static org.junit.Assert.assertEquals;
*/
public class IdentityBuilderTest extends ContainerModelBuilderTestBase {
@Test
- public void identity_config_produced() throws IOException, SAXException {
+ public void identity_config_produced_from_deployment_spec() throws IOException, SAXException {
Element clusterElem = DomBuilderTest.parse(
- "<jdisc id='default' version='1.0'>",
- " <identity>",
- " <domain>domain</domain>",
- " <service>service</service>",
- " </identity>",
- "</jdisc>");
+ "<jdisc id='default' version='1.0'/>");
+ String deploymentXml = "<deployment version='1.0' athenz-domain='domain' athenz-service='service'>\n" +
+ " <test/>\n" +
+ " <prod>\n" +
+ " <region active='true'>default</region>\n" +
+ " </prod>\n" +
+ "</deployment>\n";
+
+ ApplicationPackage applicationPackage = new MockApplicationPackage.Builder()
+ .withDeploymentSpec(deploymentXml)
+ .build();
+
+ // Override root
+ root = new MockRoot("root", applicationPackage);
+ createModel(root, DeployState.createTestState(applicationPackage), clusterElem);
- createModel(root, clusterElem);
IdentityConfig identityConfig = root.getConfig(IdentityConfig.class, "default/component/" + Identity.CLASS);
assertEquals("domain", identityConfig.domain());
assertEquals("service", identityConfig.service());
diff --git a/config-model/src/test/schema-test-files/deployment.xml b/config-model/src/test/schema-test-files/deployment.xml
index f469d22b6f0..f9a62eb648f 100644
--- a/config-model/src/test/schema-test-files/deployment.xml
+++ b/config-model/src/test/schema-test-files/deployment.xml
@@ -1,12 +1,12 @@
<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
-<deployment version='1.0'>
+<deployment version='1.0' athenz-domain='vespa' athenz-service='service'>
<upgrade policy='canary'/>
<test/>
<staging/>
<block-change revision='true' version='false' days="mon,tue" hours="14,15"/>
<block-change days="mon,tue" hours="14,15" time-zone="CET"/>
<block-upgrade days="wed" hours="16" time-zone="CET"/><!-- Tests legacy name. Remove in Vespa 7 -->
- <prod global-service-id='qrs'>
+ <prod global-service-id='qrs' athenz-service='other-service'>
<region active='true'>us-west-1</region>
<delay hours='3'/>
<region active='true'>us-central-1</region>
diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml
index 98637c03020..a02346193cc 100644
--- a/config-model/src/test/schema-test-files/services.xml
+++ b/config-model/src/test/schema-test-files/services.xml
@@ -35,10 +35,6 @@
</config>
<jdisc id='qrsCluster_1' version='1.0'>
- <identity>
- <domain>mydomain</domain>
- <service>myservice</service>
- </identity>
<rest-api path="jersey1">
<components bundle="my-bundle" />
<components bundle="other-bundle">