Can not upsert bean metadata

Hello leaf team,

I am setting up a data-service and converting it to a service-registry.

This is the bean

{
  "type": "Falc2onService",
  "displayName": "Falc2onService",
  "extendsCsv": "LeafService-1, ClassificationData-1",
  "listable": true,
  "concrete": true,
  "preferredDisplayPropName": "displayLabel",
  "objectType": "BeanMetadata"
}

This is the template

{
  "name": "Falc2onServiceTemplate",
  "fragments": {},
  "rootNodes": [
    {
      "type": "Falc2onService",
      "recursive": false,
      "includeConcreteSubTypes": false,
      "children": []
    }
  ]
}

And this is how I upsert them

        @Override
        protected void importDefaultData() {
                final String servicePrefix = "/service_registry";

                ResourceDescriptor rd = ResourceDescriptor.newBuilder()
                                .withClassInSourceSet(this.getClass())
                                .withBeanMetadataLocation(servicePrefix + "/beanmetadata")
                                .withMetadataTemplateLocation(servicePrefix + "/metadatatemplates")
                                .withEditorLayoutLocation(servicePrefix + "/editorlayouts")
                                .withLookupListLocation(servicePrefix + "/lookuplists")
                                .withListingViewLocation(servicePrefix + "/listingviews")
                                .withDataObjectLocation(servicePrefix + "/dataobjects")
                                .build();

                this.getDataService().upsertResources(ServiceDiscoveryResourceDescriptor.INSTANCE,
                                Context.makeSystemContext());
                this.getDataService().upsertResources(new Falc2onCoreResourceLocations(), Context.makeSystemContext());
                this.getDataService().upsertResources(rd, Context.makeSystemContext());

        }

In the beanMetadata collection, I can see LeafService-1 and ClassificationData-1. However, Falc2onService-1 is not there, which is the type that services use to register with, like so

 private DataObject buildServiceRegistrationObject() {
                ...

                return DataObject.newBuilder()
                                .withType("Falc2onService")
                                .withId(serviceAlias)
                                .with(LeafServiceMetadataConstants.EVENT_SERVICE_URI, eventServiceUri)
                                .with(LeafServiceMetadataConstants.SERVICE_CONTEXT, serviceContext)
                                .with(LeafServiceMetadataConstants.HEALTH_CHECK_URI, healthCheckUri)
                                .with(LeafServiceMetadataConstants.SERVICE_ALIAS, serviceAlias)
                                .with(LeafServiceMetadataConstants.SERVICE_TYPE, serviceType)
                                .withUnsafe("objectClassification", "5")
                                .build();
        }

However, this causes this error to be thrown from the service trying to register with the SR

Caused by: com.leidos.leaf.beans.exception.not.found.BeanMetadataNotFoundException: Could not find BeanMetadata with identifier: Falc2onService-1
[Note that this could be due to the entities not existing, or the User having insufficient permission to access them.]
	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[?:?]
	at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call1(AnnotatedConstructor.java:133) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:332) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer.deserializeFromObject(ThrowableDeserializer.java:111) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:219) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:186) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.leidos.leaf.util.serialization.BuildableDeserializer.deserialize(BuildableDeserializer.java:64) ~[framework-services-core-3.7.3.jar:?]
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:144) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:110) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1292) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer.deserializeWithType(DelegatingDeserializer.java:113) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:539) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer.deserializeFromObject(ThrowableDeserializer.java:104) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:219) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:186) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.leidos.leaf.util.serialization.BuildableDeserializer.deserialize(BuildableDeserializer.java:64) ~[framework-services-core-3.7.3.jar:?]
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:144) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:110) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1292) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer.deserializeWithType(DelegatingDeserializer.java:113) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:74) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:2025) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1175) ~[jackson-databind-2.13.2.2.jar:2.13.2.2]
	at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:803) ~[jackson-jaxrs-base-2.13.2.jar:2.13.2]
	at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.readFrom(AbstractReaderInterceptorContext.java:101) ~[resteasy-core-5.0.2.Final.jar:5.0.2.Final]
	at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:80) ~[resteasy-core-5.0.2.Final.jar:5.0.2.Final]
	at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:217) ~[resteasy-client-5.0.2.Final.jar:5.0.2.Final]
	at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:90) ~[resteasy-core-5.0.2.Final.jar:5.0.2.Final]
	at org.jboss.resteasy.specimpl.AbstractBuiltResponse.readEntity(AbstractBuiltResponse.java:262) ~[resteasy-core-5.0.2.Final.jar:5.0.2.Final]
	... 9 more

There are no errors in the logs of the service-registry until I deploy the service that tries to register as a Falc2onService-1. Then this is thrown

[Note that this could be due to the entities not existing, or the User having insufficient permission to access them.]
com.leidos.leaf.beans.exception.not.found.BeanMetadataNotFoundException: Could not find BeanMetadata with identifier: Falc2onService-1
[Note that this could be due to the entities not existing, or the User having insufficient permission to access them.]
	at com.leidos.leaf.beans.exception.not.found.BeanMetadataNotFoundException.exceptionForIdentifiers(BeanMetadataNotFoundException.java:41) ~[framework-services-core-3.6.1.jar:?]
	at com.leidos.leaf.metadata.service.beanmetadata.dao.mongo.BeanMetadataDaoMongo.lambda$loadLatestEditionsRx$15(BeanMetadataDaoMongo.java:452) ~[framework-services-mongo-3.6.1.jar:?]
...

Oddly enough, if I remove the extension of classificationData and just have

{
  "type": "Falc2onService",
  "displayName": "Falc2onService",
  "extendsCsv": "LeafService-1",
  "listable": true,
  "concrete": true,
  "preferredDisplayPropName": "displayLabel",
  "objectType": "BeanMetadata"
}

and dont upsert those resources

         */
        @Override
        protected void importDefaultData() {
                final String servicePrefix = "/service_registry";

                ResourceDescriptor rd = ResourceDescriptor.newBuilder()
                                .withClassInSourceSet(this.getClass())
                                .withBeanMetadataLocation(servicePrefix + "/beanmetadata")
                                .withMetadataTemplateLocation(servicePrefix + "/metadatatemplates")
                                .withEditorLayoutLocation(servicePrefix + "/editorlayouts")
                                .withLookupListLocation(servicePrefix + "/lookuplists")
                                .withListingViewLocation(servicePrefix + "/listingviews")
                                .withDataObjectLocation(servicePrefix + "/dataobjects")
                                .build();

                this.getDataService().upsertResources(ServiceDiscoveryResourceDescriptor.INSTANCE,
                                Context.makeSystemContext());
              //  this.getDataService().upsertResources(new Falc2onCoreResourceLocations(), Context.makeSystemContext());
                this.getDataService().upsertResources(rd, Context.makeSystemContext());

        }

Then it works fine and Falc2onService shows in the DB.
This is the Falc2onResourceLocation class

package com.leidos.falc2on.core.metadata.resources;

import java.util.Optional;

import com.leidos.leaf.util.resource.IResourceDescriptor;

public final class Falc2onCoreResourceLocations implements IResourceDescriptor {

    // **********************************
    // *  Constants
    // **********************************

    public static final String BEAN_METADATA_DIR = "/falc2on/core/bean/metadata";
    public static final String LOOKUP_LIST_DIR = "/falc2on/core/lookup/list";
    public static final String METADATA_TEMPLATE_DIR = "/falc2on/core/metadata/template";


	@Override
	public Optional<String> getBeanMetadataLocation() {
		return Optional.of(BEAN_METADATA_DIR);
	}

	@Override
	public Optional<String> getMetadataTemplateLocation() {
		return Optional.of(METADATA_TEMPLATE_DIR);
	}

	@Override
	public Optional<String> getLookupListLocation() {
		return Optional.of(LOOKUP_LIST_DIR);
	}
}

Any ideas why Falc2onService-1 is not upserted?

Something to add here. I tested thing by just adding in our teams core resources, like so

{
  "type": "Falc2onService",
  "displayName": "Falc2onService",
  "extendsCsv": "ClassificationData-1",
  "listable": true,
  "concrete": true,
  "preferredDisplayPropName": "displayLabel",
  "objectType": "BeanMetadata"
}
        @Override
        protected void importDefaultData() {
                final String servicePrefix = "/service_registry";

                ResourceDescriptor rd = ResourceDescriptor.newBuilder()
                                .withClassInSourceSet(this.getClass())
                                .withBeanMetadataLocation(servicePrefix + "/beanmetadata")
                                .withMetadataTemplateLocation(servicePrefix + "/metadatatemplates")
                                .withEditorLayoutLocation(servicePrefix + "/editorlayouts")
                                .withLookupListLocation(servicePrefix + "/lookuplists")
                                .withListingViewLocation(servicePrefix + "/listingviews")
                                .withDataObjectLocation(servicePrefix + "/dataobjects")
                                .build();

                // this.getDataService().upsertResources(ServiceDiscoveryResourceDescriptor.INSTANCE,
                // Context.makeSystemContext());
                this.getDataService().upsertResources(new Falc2onCoreResourceLocations(), Context.makeSystemContext());
                // this.getDataService().upsertResources(rd, Context.makeSystemContext());

        }

The metadata collection had 20 documents in it. I then added back in just the leaf stuff and our core resources

{
  "type": "Falc2onService",
  "displayName": "Falc2onService",
  "extendsCsv": "LeafService-1, ClassificationData-1",
  "listable": true,
  "concrete": true,
  "preferredDisplayPropName": "displayLabel",
  "objectType": "BeanMetadata"
}
        @Override
        protected void importDefaultData() {
                final String servicePrefix = "/service_registry";

                ResourceDescriptor rd = ResourceDescriptor.newBuilder()
                                .withClassInSourceSet(this.getClass())
                                .withBeanMetadataLocation(servicePrefix + "/beanmetadata")
                                .withMetadataTemplateLocation(servicePrefix + "/metadatatemplates")
                                .withEditorLayoutLocation(servicePrefix + "/editorlayouts")
                                .withLookupListLocation(servicePrefix + "/lookuplists")
                                .withListingViewLocation(servicePrefix + "/listingviews")
                                .withDataObjectLocation(servicePrefix + "/dataobjects")
                                .build();

                this.getDataService().upsertResources(ServiceDiscoveryResourceDescriptor.INSTANCE,
                                Context.makeSystemContext());
                this.getDataService().upsertResources(new Falc2onCoreResourceLocations(), Context.makeSystemContext());
                // this.getDataService().upsertResources(rd, Context.makeSystemContext());

        }

Here, I added in LeafService-1 and now there is only 5 documents in the metadata collection? The SR also restarted once. Is it possible the SR is having a resource issue?

Ok so looking into the SR, I see that it restarted due to lack of memory

Containers:
  leaf-service:
    Container ID:   docker://c46e3ca875af578971b742ec3c7a75bc4b522c4bae4486bb28caab63ae3ef4ac
    Image:          service-registry:9a9cd7d8936ffa5c3026e48e874a113b0a63cc075c4b193fe0d7565628d4c829
    Image ID:       docker://sha256:9a9cd7d8936ffa5c3026e48e874a113b0a63cc075c4b193fe0d7565628d4c829
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 07 Nov 2022 07:55:55 -0500
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
      Started:      Mon, 07 Nov 2022 04:21:59 -0500
      Finished:     Mon, 07 Nov 2022 07:55:54 -0500
    Ready:          True
    Restart Count:  106
    Limits:
      cpu:     300m
      memory:  500Mi
    Requests:
      cpu:      200m
      memory:   400Mi

I increased the resources via values.yaml, however they don’t see to have taken effect based on the resources listed there^

values.yaml

fullnameOverride: service-registry
enableIngress: false
enableVirtualService: true
leaf-service:
  virtualService: |
    gateways:
    - istio-system/istio-ingressgateway
    hosts:
    - '*'
    http:
    - match:
      - uri:
          prefix: /service-registry/
      rewrite:
        uri: /
      route:
      - destination:
          host: service-registry
  resources:
    limits:
      cpu: 1000m
      memory: 800Mi
    requests:
      cpu: 200m
      memory: 400Mi
...

Ok, I got this sorted out. This is the proper values.yaml

fullnameOverride: service-registry
enableIngress: false
enableVirtualService: true
resources:
  limits:
    cpu: 1000m
    memory: 800Mi
  requests:
    cpu: 200m
    memory: 400Mi
virtualService: |
  gateways:
  - istio-system/istio-ingressgateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /service-registry/
    rewrite:
      uri: /
    route:
    - destination:
        host: service-registry
...

The SR can now upsert all the metadata. So I guess it ran out of memory when doing the upsertion since only half of the core resources would actually be upserted

1 Like

Yeah, indentation can be a bit of a pain with Kubernetes yaml files. So it seems like you were able to troubleshoot this successfully yourself – I would definitely recommend giving this LKB page on resources for some more info just in case you need info for the future.

1 Like