How to add a list property to an entity using gcloud Java client? - google-cloud-platform

I can set a property to a new entity:
Entity.Builder builder = Entity.builder(actKey);
builder.set("name", someName);
I can see a method to add a list as a property:
List<Value<String>> aliases = new ArrayList<>();
builder.set("aliases", aliases);
I cannot find, however, how to create this Value<String>. There is a DatastoreHelper.makeValue() method in DatastoreV1, but it creates a different Value object.

Looking at the source code for gcloud, the answer is this:
Builder aliases = ListValue.builder();
while (someIterator.hasNext()) {
aliases.addValue(StringValue.builder("some string").build());
}
builder.set("aliases", aliases.build());

Related

M2Doc error <---Couldn't find the 'getText(EClassifier=Model)' service

I was using m2doc programmatically, and this is my code.
final URI templateURI = URI.createFileURI(templateName+"."+M2DocUtils.DOCX_EXTENSION_FILE);
final URI modelURI = URI.createFileURI(modelName);
// can be empty, if you are using a Generation use GenconfUtils.getOptions(generation)
final Map<String, String> options = new HashMap<>();
List<Exception> exceptions = new ArrayList<>();
final ResourceSet resourceSetForModels = M2DocUtils.createResourceSetForModels(exceptions , "key", new ResourceSetImpl(), options);
//resourceSetForModels.getResource(modelURI, true);
final Resource r = resourceSetForModels.getResource(modelURI, true);
System.out.println(r.getContents());
final EObject value = r.getContents().get(0);
// if you are using a Generation, use GenconfUtils.getQueryEnvironment(resourceSetForModels, generation)
final IQueryEnvironment queryEnvironment = M2DocUtils.getQueryEnvironment(resourceSetForModels, templateURI, options); // delegate to IServicesConfigurator
final IClassProvider classProvider = new ClassProvider(this.getClass().getClassLoader()); // use M2DocPlugin.getClassProvider() when running inside Eclipse
final Monitor monitor = new BasicMonitor.Printing(System.out);
try (DocumentTemplate template = M2DocUtils.parse(resourceSetForModels.getURIConverter(), templateURI, queryEnvironment, classProvider, monitor)) {
// validate
final ValidationMessageLevel validationLevel = M2DocUtils.validate(template, queryEnvironment, monitor);
if (validationLevel != ValidationMessageLevel.OK) {
final URI validationResulURI = URI.createFileURI(templateName+"-validation."+M2DocUtils.DOCX_EXTENSION_FILE); // some place to serialize the result of the validation
M2DocUtils.serializeValidatedDocumentTemplate(resourceSetForModels.getURIConverter(), template, validationResulURI);}
//generate
final Map<String, Object> variables = new HashMap<>(); // your variables and values
variables.put("self", value);
final URI outputURI = URI.createFileURI(templateName+"-result."+M2DocUtils.DOCX_EXTENSION_FILE); // some place to serialize the result of the generation
M2DocUtils.generate(template, queryEnvironment, variables, resourceSetForModels, outputURI, monitor);
}finally {
M2DocUtils.cleanResourceSetForModels("key", resourceSetForModels);
}
And when I ran the program, the validation file was created, and it shows lots of errors. The errors were like this: <---Couldn't find the 'getText(EClassifier=Model)' service. They appeared everywhere I used the service getText().
When I use the same template and the same uml file to generate document by using the m2doc plugin in eclipse, it went alright.
I wonder if my query environment setting was wrong.
Thank you if you can help me.
M2DocUtils.parse() initialize the IQueryEnvironment with services and nsURIs imported in the template. So you should not need to add anything.
If you are running inside Eclipse you should use:
final IClassProvider classProvider = M2DocPlugin.getClassProvider()
It should help loading your service Class (it use OSGi to load classes from bundles).
You can also check if any TemplateValidationMessage are present with more details:
DocumentTemplate.getBody().getValidationMessages()
At this point either the UML metamodel is not registered or it's your service Class (more likely).
You can register the UML EPackage and see if it helps:
queryEnvironment.registerEPackage(UMLPackage.eINSTANCE)
You can also try to register your service class:
final Set<IService> s = ServiceUtils.getServices(queryEnvironment, SomeServiceClass.class);
ServiceUtils.registerServices(queryEnvironment, s);

How to extend user schema using WSO2 charon scim library

I am creating a SCIM server using Charon library. How to extend user schema using WSO2 charon scim library?
You have two options to extend the schema using charon library.
Option 1:
Define the attribute definitions in a file and build the schema using the file.
When writing that file, the final config in the configuration file should be the definition of the extension.
Method to use in charon: https://github.com/wso2/charon/blob/27562f69ce5b23b4e85015daf5aa11c651a91a8c/modules/charon-core/src/main/java/org/wso2/charon3/core/config/SCIMUserSchemaExtensionBuilder.java#L63
sample java code to build schema using this method:
String schemaFilePath = "<absolute path to the schema defined file>";
SCIMUserSchemaExtensionBuilder.getInstance().buildUserSchemaExtension(schemaFilePath);
AttributeSchema extensionSchema = SCIMUserSchemaExtensionBuilder.getInstance().getExtensionSchema();
// print the attribute URIs in the built schema
extensionSchema.getSubAttributeSchemas().stream().forEach(e->System.out.print(e.getURI() + "\n"));
refer: https://github.com/AnuradhaSK/schema-extension/blob/cea1fa636bea2bb1e599ac9c71c6c45eaa339199/src/main/java/ScimSchemas.java#L29-L35
Format of the file: https://github.com/AnuradhaSK/schema-extension/blob/main/src/main/resources/custom-schema
Option 2:
Use SCIMCustomSchemaExtensionBuilder in charon.
You have to define the extended schema URI first.
Then create
SCIMCustomAttribute objects for each attribute you need to add to the extended schema. You have to define the default set of attribute properties mentioned in the scim schema for an attribute
Finally create another SCIMCustomAttribute to represent the extended schema
Put all objects to a List and call buildUserCustomSchemaExtension method in SCIMCustomSchemaExtensionBuilder
Method to use in charon:
https://github.com/wso2/charon/blob/27562f69ce5b23b4e85015daf5aa11c651a91a8c/modules/charon-core/src/main/java/org/wso2/charon3/core/config/SCIMCustomSchemaExtensionBuilder.java#L71
sample java code:
SCIMCustomSchemaExtensionBuilder.getInstance().setURI("urn:scim:custom:extended:schemas");
LOG.info("====Attributes of extended schema using custom attributes===");
// Sub attribute of the schema.
Map<String, String> subAttributeProperties = new HashMap<>();
subAttributeProperties.put("attributeURI","urn:scim:custom:extended:schemas:vehicleNo");
subAttributeProperties.put("attributeName","vehicleNo");
subAttributeProperties.put("dataType","string");
subAttributeProperties.put("multiValued","false");
subAttributeProperties.put("description","User's vehicle number");
subAttributeProperties.put("required","false");
subAttributeProperties.put("caseExact","false");
subAttributeProperties.put("mutability","readWrite");
subAttributeProperties.put("returned","default");
subAttributeProperties.put("uniqueness","none");
subAttributeProperties.put("canonicalValues","[]");
SCIMCustomAttribute scimCustomAttribute = new SCIMCustomAttribute();
scimCustomAttribute.setProperties(subAttributeProperties);
// Schema object.
Map<String, String> schemaObjectProperties = new HashMap<>();
schemaObjectProperties.put("attributeURI","urn:scim:custom:extended:schemas");
schemaObjectProperties.put("attributeName","urn:scim:custom:extended:schemas");
schemaObjectProperties.put("dataType","complex");
schemaObjectProperties.put("multiValued","false");
schemaObjectProperties.put("description","Extended custom schema");
schemaObjectProperties.put("required","false");
schemaObjectProperties.put("caseExact","false");
schemaObjectProperties.put("mutability","readWrite");
schemaObjectProperties.put("returned","default");
schemaObjectProperties.put("uniqueness","none");
schemaObjectProperties.put("subAttributes","vehicleNo");
schemaObjectProperties.put("canonicalValues","[]");
SCIMCustomAttribute schemaAttribute = new SCIMCustomAttribute();
schemaAttribute.setProperties(schemaObjectProperties);
List<SCIMCustomAttribute> attributeList = new ArrayList<>();
attributeList.add(scimCustomAttribute);
attributeList.add(schemaAttribute);
AttributeSchema customExtendedSchema = SCIMCustomSchemaExtensionBuilder.getInstance().buildUserCustomSchemaExtension(attributeList);
customExtendedSchema.getSubAttributeSchemas().stream().forEach(e->System.out.print(e.getURI() + "\n"));
refer: https://github.com/AnuradhaSK/schema-extension/blob/cea1fa636bea2bb1e599ac9c71c6c45eaa339199/src/main/java/ScimSchemas.java#L39-L78

Google Cloud Data flow : CloudBigtableScanConfiguration.withScan(), how to pass dynamic filter values?

SourceLocation is prefix for my Bigtable, which is fetched from application.properties. Is there a way to fetch it dynamically while running the data flow template?
My Pipeline:
pipeline.apply("ReadTable", Read.from(CloudBigtableIO.read(configSetUp(options))))
CloudBigtableScanConfiguration
private static CloudBigtableScanConfiguration configSetUp(LocationSetupOptions options) {
ValueProvider<Integer> pageFilter = options.getPageFilter();
Scan scan = new Scan(Bytes.toBytes(options.getSourceLocation().get()));
FilterList filterList = new FilterList();
PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes(options.getSourceLocation().get()));
filterList.addFilter(new PageFilter(Long.valueOf(pageFilter.get())));
filterList.addFilter(prefixFilter);
scan.setFilter(filterList);
return new CloudBigtableScanConfiguration.Builder()
.withProjectId(options.getProjectId())
.withInstanceId(options.getInstanceId())
.withTableId(options.getTableId())
.withScan(scan)
.build();}
There are two clients for Bigtable CloudBigtableIO and BigtableIO. The CloudBigtableIO parameters are not updated to be modified by templates via a ValueProvider but BigtableIO is compatible with ValueProviders.
In your particular case if you are looking for ValueProvider to be used along with template then I would recommend that you move to using BigtableIO. A sample can be found here AvroToBigtable.
UPDATE
The #Default.InstanceFactory can be used to specify a user-provided factory method to generate default values for a parameter. With this, you could read the default value from a resource file inside of your DefaultValueFactory implementation.
As an example, you can check how WindowedWordCount defines DefaultToCurrentSystemTime to annotate the minTimestampMillis parameter:

How do we retrieve values of Custom Lists(dropdown) in Netsuite

I have record type "XYZ" which has field called "award area" which is of type list/record. "award area" is of type custom list and is a drop down control.
Using Suitetalk how can I retrieve those values from that drop down?
Thank you
I think something like this should work. It's for translating the results from the internalId's returned into the actual text type, you maybe be able to leverage it in another way. Maybe you could create a lookup list with something like this(C#):
public Dictionary<string, Dictionary<long, string>> getCustomFieldLists()
{
return
nsService.search(new CustomListSearch())
.recordList.Select(a => (CustomList) a)
.ToDictionary(a => a.name,
a => a.customValueList.customValue
.ToDictionary(b => b.valueId, c => c.value));
}
var valueLookup = getCustomFieldLists()["award area"];
Here's how I did it for myself, because I was irritated with the fact the NetSuite doesn't just provide us an easy way to access these. And I wanted the following data for reference:
The Internal ID of the Custom List
The Name of the Custom List
The Internal ID of the Custom List Item
The name Value of the Custom List Item
I wanted/needed access to all of those things, and I wanted to be able to obtain the name Value of the Custom List Item by just providing the Internal ID of the Custom List and the Internal ID of the Custom List Item. So, in my homemade integration client, similar to David Rogers' answer, but without all the fancy Linq, I figured out that the best solution was a Dictionary>>.
This way, for the outer Dictionary, I could set the key to the internal IDs of the Custom Lists, and for the inner Dictionary I could set the key to the internal IDs of the Custom List Items themselves. Then, I would get the name of the Custom List for "free" as the beginning part of the Tuple, and the actual name Value for "free" as the value of the internal Dictionary.
Below is my method code to generate this object:
/// <summary>
/// Gets the collection of all custom lists, and places it in the public CustomListEntries object
/// </summary>
/// <returns></returns>
private Dictionary<string, Tuple<string, Dictionary<long, string>>> GetCustomLists()
{
Dictionary<string, Tuple<string, Dictionary<long, string>>> customListEntries = new Dictionary<string, Tuple<string, Dictionary<long, string>>>();
SearchPreferences sp = SuiteTalkService.searchPreferences; //Store search preferences to reset back later, just need body fields this one time
SuiteTalkService.searchPreferences = new SearchPreferences() { bodyFieldsOnly = false };
SearchResult sr = SuiteTalkService.search(new CustomListSearch());
SuiteTalkService.searchPreferences = sp; //Restore search preferences
foreach (CustomList cl in sr.recordList)
{
Dictionary<long, string> customListItems = new Dictionary<long, string>();
if (cl.customValueList == null) continue;
foreach (CustomListCustomValue clcv in cl.customValueList.customValue)
{
customListItems.Add(clcv.valueId, clcv.value);
}
customListEntries.Add(cl.internalId, new Tuple<string, Dictionary<long, string>>(cl.name, customListItems));
}
return customListEntries;
}
Then, in the constructors of my Integration class, I can set my object to the return result:
public Dictionary<string, Tuple<string, Dictionary<long, string>>> CustomListEntries = GetCustomLists();
And finally, whenever I need access TO those values, since I set all of this up ahead of time, I can do the following:
dr[Class] = SuiteTalkIntegrator.CustomListEntries[lorr.typeId].Item2[long.Parse(lorr.internalId)];
In this case above, my "lorr" object is a ListOrRecordRef object that I obtained from the SearchColumnSelectCustomField.searchValue from the search results of a SavedSearch. I don't know if this will work for anyone else that finds this code, but since I was frustrated in finding an easy answer to this problem, I thought I'd share my solution with everyone.
Frankly, I'm most frustrated that this functionality isn't just given to us out of the box, but I've noticed that NetSuite has made a lot of bad design choices in their SuiteTalk API, like not making a custom class of "RecordField" for their record fields and not placing their record fields under an IEnumerable of RecordField so that programmers can loop through all values in a record in a generic way without having to EXPLICITLY name them and re-construct the same code logic over and over again... ugh...

Doctrine - I'm getting Entity class instead of Repository class

I create instance of entity manager
$this->em = Connection::MainMySql()->GetEntityManager();
After some queries I try to get object from a Repository class.
$usersArray = $this->em->createQueryBuilder()
->select("us")
->from('Model\Repo\mytables\User', "us")
->where("us.idUser = :idUser")
->setParameter("idUser", $idUser)
->getQuery()
->execute();
Why do I then get list of objects of class Model\Entity\mytables\User instead of Model\Repo\mytables\User even after I specify desired class in from(...) section?
In fact, a repository cannot be used as a representation of a database entry.
In other words, Repositories should contain methods to retrieve/create/update/delete database entries represented by entities.
This is why the EntityManager is called Entity Manager, it manages Entities and not Repository classes.
For instance, you can perfectly do:
// Return an instance of the Repository Model\Repo\mytables\User
$repository = $this->em->getRepository('Model\Entity\mytables\User');
// The repository is used to create the QueryBuilder, so the from statement is already filled by doctrine as model\Entity\mytables\User
$query = $repository->createQueryBuilder('u')
// ...
This is also why you can do:
$repository = $this->em->getRepository('Model\Entity\mytables\User');
// Return all entries of the 'users' table as Model\Entity\mytables\User instances
$users = $repository->findAll();
I'm surprised that the from statement of your query doesn't produce an error such as "Model\Entity\mytables\User is not a valid entity".
Also, your structure looks confusing, you must differentiate properly Repositories (the Models) from Entities in order to use them according to their respective roles.