Docker expose service to achieve dockerized wordpress multisite - wordpress

I have been trying to enable Wordpress multisite network for a dockerized Wordpress application.
The application can be accessed via IP and port like this:
http://0.0.0.0:8282
When I enable WP_ALLOW_MULTISITE in wp-config.php I get the error from Wordpress that I can not use domain names with port e.g. :8282
in this particular case.
So I was looking for a way how to expose some domain name from Docker container, instead of 0.0.0.0:8282
I found this example:
https://www.theimpossiblecode.com/blog/docker-wordpress-multisite-with-subdomains/
And I went over the example to make it work, as it is described. Then I intend to look for a way how to implement it for my particular application.
The problem:
I started by exposing a service, described on linked page:
https://www.theimpossiblecode.com/blog/docker-expose-service/
I used the enclosed docker-compose.yml from that page, and when I run
$ docker-compose up -d
the containers appear to be working:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edaeb215b3eb wordpress:latest "docker-entrypoint.s…" 34 minutes ago Up 34 minutes 80/tcp dockwpress_wordpress_1
5dc6fa8480c6 mysql:5.7 "docker-entrypoint.s…" 34 minutes ago Up 34 minutes 3306/tcp, 33060/tcp dockwpress_db_1
But, I can't access: http://dockerwp and $ dig dockerwp yields this:
; <<>> DiG 9.10.6 <<>> dockerwp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 23290
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;dockerwp. IN A
;; Query time: 34 msec
;; SERVER: 10.11.137.100#53(10.11.137.100)
;; WHEN: Thu Dec 13 17:05:34 GMT 2018
;; MSG SIZE rcvd: 37
When inspecting the container I see that the dockerwp domain name has been exposed (the "com.theimpossiblecode.expose.host": "dockerwp" line).
$ docker inspect edaeb215b3eb
[
{
"Id": "edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb",
"Created": "2018-12-13T16:28:55.122420503Z",
"Path": "docker-entrypoint.sh",
"Args": [
"apache2-foreground"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 10823,
"ExitCode": 0,
"Error": "",
"StartedAt": "2018-12-13T16:28:55.733061919Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:55b751a7663f6d4fdd0d5f3785b0a846868147dceff99dd169f0a33214be3452",
"ResolvConfPath": "/var/lib/docker/containers/edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb/hostname",
"HostsPath": "/var/lib/docker/containers/edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb/hosts",
"LogPath": "/var/lib/docker/containers/edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb/edaeb215b3eb37e681fed81099c2de65425a4a6c735529366112ba5436e937cb-json.log",
"Name": "/dockwpress_wordpress_1",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "dockwpress_default",
"PortBindings": {},
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": [],
"CapAdd": null,
"CapDrop": null,
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": null,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/8ab6c3eb7bb9e80de85a5c39849775d339d9466c182b236eca411f1cb32d7f29-init/diff:/var/lib/docker/overlay2/44b78d4977abf7cab796267c277db0e31efd5190f917dce4167237070fb0317e/diff:/var/lib/docker/overlay2/1d3fb40ede0d5e2626d4d1ea19e93cb15702a7bcb569bf2811e652d25409623f/diff:/var/lib/docker/overlay2/f59d3c961f65e7ad1297bf888ed04905dff998a31a5796c7c903a8f854749a3b/diff:/var/lib/docker/overlay2/af222f8ba1e9c68b16935d08a0325ec8ff173a2944082e8d3e568a2c738d591f/diff:/var/lib/docker/overlay2/1bac18c6dc58c3ebd7982dd3ccdfb7fdbc4037de6277c20d84baba95babaf4c1/diff:/var/lib/docker/overlay2/32df749d5027d957ebba6167f8715bbbc117c0787c8d5849f318391d427dfcaf/diff:/var/lib/docker/overlay2/e6927c13204369a44dc8f4de4a8ab8a3307b0f8fa5eb758a565a67a1b923451a/diff:/var/lib/docker/overlay2/a6299eec8f02b0c2a190a9646b7576209e0e39f6bae1d81f543daaabe0dd89d4/diff:/var/lib/docker/overlay2/d0e4d7ff78e7373c4f3885e8cad840617764e9a803bda6eb30e681cdc910bf51/diff:/var/lib/docker/overlay2/fc48c85e773fd6d0e52b4a84116224d2ee0a396a470df44b009fb56ef8276704/diff:/var/lib/docker/overlay2/77aea6e322140a30aff363c97e67bad3f2ab78f301ebdadc89275f9e1e86ad0d/diff:/var/lib/docker/overlay2/fec4aae10fb644332df8a1c286c9635a1ae85f2d9aaf8838ae08b7e6f3268a8d/diff:/var/lib/docker/overlay2/41bfdb4f1afa0d88890af4deb33c403e5816a6b2823d3a9ed5fb19079b4faa9b/diff:/var/lib/docker/overlay2/5aa746815fbdaeedc7a727ca34072f1183af9bc0ba7908b480e37ee9f5884761/diff:/var/lib/docker/overlay2/aa6c25c7e61f3512a55f69ed5c39f492b80a500704bdc9a91af8ff811f74f58d/diff:/var/lib/docker/overlay2/41c27f1bb64072e7deebc7eee4b46f3c38b63e2bc56ebfaf9c88159f1d6c67c2/diff:/var/lib/docker/overlay2/512ece5edecc822e72e5d939d75339e02582696dbc5205f756516c4b635ff9d3/diff:/var/lib/docker/overlay2/7bd7bb38c22c9ee4dd2c38d2c32ac12bbb2034c759879a26b73b351ac7a5e26e/diff:/var/lib/docker/overlay2/602c7d2fa85ca8e4945236214ffb852abcfd716f5626d273b510b470d7878d02/diff",
"MergedDir": "/var/lib/docker/overlay2/8ab6c3eb7bb9e80de85a5c39849775d339d9466c182b236eca411f1cb32d7f29/merged",
"UpperDir": "/var/lib/docker/overlay2/8ab6c3eb7bb9e80de85a5c39849775d339d9466c182b236eca411f1cb32d7f29/diff",
"WorkDir": "/var/lib/docker/overlay2/8ab6c3eb7bb9e80de85a5c39849775d339d9466c182b236eca411f1cb32d7f29/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "bd2706aae2dbddaa65a85e77ca89efc3844dc600f72e1e8b1f9b6803cbb8459c",
"Source": "/var/lib/docker/volumes/bd2706aae2dbddaa65a85e77ca89efc3844dc600f72e1e8b1f9b6803cbb8459c/_data",
"Destination": "/var/www/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "edaeb215b3eb",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"WORDPRESS_DB_HOST=db:3306",
"WORDPRESS_DB_USER=wordpress",
"WORDPRESS_DB_PASSWORD=wordpress",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PHPIZE_DEPS=autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c",
"PHP_INI_DIR=/usr/local/etc/php",
"APACHE_CONFDIR=/etc/apache2",
"APACHE_ENVVARS=/etc/apache2/envvars",
"PHP_EXTRA_BUILD_DEPS=apache2-dev",
"PHP_EXTRA_CONFIGURE_ARGS=--with-apxs2 --disable-cgi",
"PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie",
"GPG_KEYS=1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F",
"PHP_VERSION=7.2.13",
"PHP_URL=https://secure.php.net/get/php-7.2.13.tar.xz/from/this/mirror",
"PHP_ASC_URL=https://secure.php.net/get/php-7.2.13.tar.xz.asc/from/this/mirror",
"PHP_SHA256=14b0429abdb46b65c843e5882c9a8c46b31dfbf279c747293b8ab950c2644a4b",
"PHP_MD5=",
"WORDPRESS_VERSION=5.0",
"WORDPRESS_SHA1=67758958f14c1dcefe37ce6558d470a4e142893b"
],
"Cmd": [
"apache2-foreground"
],
"ArgsEscaped": true,
"Image": "wordpress:latest",
"Volumes": {
"/var/www/html": {}
},
"WorkingDir": "/var/www/html",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"com.docker.compose.config-hash": "c8ce0ffef4cef318c23c0e6142dcb5b42a97df29507969c72a99e95b3343f0ec",
"com.docker.compose.container-number": "1",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "dockwpress",
"com.docker.compose.service": "wordpress",
"com.docker.compose.version": "1.23.2",
"com.theimpossiblecode.expose.host": "dockerwp"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "83bdba7bf688685fa842ab8c1c38a53f26af088c2fd1063492ae55cb73cc6cd6",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/83bdba7bf688",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"dockwpress_default": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"wordpress",
"edaeb215b3eb"
],
"NetworkID": "6b7d8cc32a6e208f379a8ecfdf88910c85c575e284ad2e3632520fe86ec937ad",
"EndpointID": "a7d991d525463bb83b2eedb78baf59358d8a543f3b5244034eaea6cce99ef525",
"Gateway": "172.28.0.1",
"IPAddress": "172.28.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:1c:00:03",
"DriverOpts": null
}
}
}
}
]
What could be causing the http://dockerwp to be not accessible?
Browser shows this error:
This site can’t be reached dockerwp’s server IP address could not be found.
Did you mean http://docker.com/?
Search Google for docker wp
ERR_NAME_NOT_RESOLVED
Thank you.

dockerwp in http://dockerwp is a domain name that does not exist.
You example is only valid if you deploy your wp site to their platform which will give you a subdomain called "dockerwp". The label om.theimpossiblecode.expose.host is read by their reverse proxy to create this effect.
In conclusion you can't set hostname with this configuration. You will be better off just access your site with localhost:port.

The solution is to use Nginx proxy server e.g. https://github.com/jwilder/nginx-proxy
So by using two containers, one is the proxy and another is Wordpress application docker container, you can add vhost entries to /etc/hosts as 127.0.0.1 devwebsite.local for any of required virtual hosts. Those have to be configured for the WP container, the VIRTUAL_HOST env. variable.
Here is the example:https://github.com/djuro/dockerMultisiteWordpress, the Dockerfile and docker-compose.yml in particular.
I used 2 more containers, for database and GUI db tool (Adminer), but those are both optional.

Related

jq array filter for nested array elements

I am trying to add a new user in below json which matches group NP01-RW. i am able to do without NP01-RW but not able to select users under NP01-RW and return updated json.
{
"id": 181,
"guid": "c9b7dbde-63de-42cc-9840-1b4a06e13364",
"isEnabled": true,
"version": 17,
"service": "Np-Hue",
"name": "DATASCIENCE-CUROPT-RO",
"policyType": 0,
"policyPriority": 0,
"isAuditEnabled": true,
"resources": {
"database": {
"values": [
"hive_cur_acct_1dev",
"hive_cur_acct_1eng",
"hive_cur_acct_1rwy",
"hive_cur_acct_1stg",
"hive_opt_acct_1dev",
"hive_opt_acct_1eng",
"hive_opt_acct_1stg",
"hive_opt_acct_1rwy"
],
"isExcludes": false,
"isRecursive": false
},
"column": {
"values": [
"*"
],
"isExcludes": false,
"isRecursive": false
},
"table": {
"values": [
"*"
],
"isExcludes": false,
"isRecursive": false
}
},
"policyItems": [
{
"accesses": [
{
"type": "select",
"isAllowed": true
},
{
"type": "update",
"isAllowed": true
},
{
"type": "create",
"isAllowed": true
},
{
"type": "drop",
"isAllowed": true
},
{
"type": "alter",
"isAllowed": true
},
{
"type": "index",
"isAllowed": true
},
{
"type": "lock",
"isAllowed": true
},
{
"type": "all",
"isAllowed": true
},
{
"type": "read",
"isAllowed": true
},
{
"type": "write",
"isAllowed": true
}
],
"users": [
"user1",
"user2",
"user3"
],
"groups": [
"NP01-RW"
],
"conditions": [],
"delegateAdmin": false
},
{
"accesses": [
{
"type": "select",
"isAllowed": true
}
],
"users": [
"user1"
],
"groups": [
"NP01-RO"
],
"conditions": [],
"delegateAdmin": false
}
],
"denyPolicyItems": [],
"allowExceptions": [],
"denyExceptions": [],
"dataMaskPolicyItems": [],
"rowFilterPolicyItems": [],
"options": {},
"validitySchedules": [],
"policyLabels": [
"DATASCIENCE-CurOpt-RO_NP01"
]
}
below is what i have tried but it returns part of the JSON matching NP01-RW and not full JSON
jq --arg username "$sync_userName" '.policyItems[] | select(.groups[] | IN("NP01-RO")).users += [$username]' > ${sync_policyName}.json
Operator precedence in jq is not always intuitive. Your program is parsed as:
.policyItems[] | (select(.groups[] | IN("NP01-RO")).users += [$username])
Which first streams all policyItems and only then changes them, leaving you with policyItems only in the output.
You need to make sure that the stream selects the correct values, which you can then assign:
(.policyItems[] | select(.groups[] | IN("NP01-RO")).users) += [$username]
This will do the assignment, but still return the full input (.).

Parsing json file with jq from HPE iLO

I have a json file pulled from an HPE iLO interface with the snmp configuration. It looks like:
[
{
"Comments": {
"BIOSDate": "01/23/2021",
"BIOSFamily": "U30",
"Manufacturer": "HPE",
"Model": "ProLiant DL380 Gen10",
"SerialNumber": "5UNESX378",
"iLOVersion": "iLO 5 v2.65"
}
},
{
"#HpeiLOSnmpService.v2_3_0.HpeiLOSnmpService": {
"/redfish/v1/Managers/1/SnmpService/": {
"#odata.context": "/redfish/v1/$metadata#HpeiLOSnmpService.HpeIloSnmpService",
"#odata.id": "/redfish/v1/Managers/1/SnmpService",
"Actions": {
"#HpeIloSnmpService.SendSNMPTestAlert": {
"target": "/redfish/v1/Managers/1/SnmpService/Actions/HpeILOSnmpService.SendSNMPTestAlert/"
}
},
"AlertDestinationAssociations": [
{
"SNMPAlertProtocol": "SNMPv3Trap",
"SecurityName": null
}
],
"AlertDestinations": [
"1.2.3.4",
"5.6.7.8",
null,
null
],
"AlertsEnabled": true,
"Name": "SnmpService"
},
"PeriodicHSATrapConfig": "Disabled",
"ReadCommunities": [
"",
"",
""
],
"Role": "",
"RoleDetail": "",
"SNMPAlertDestinations": {
"#odata.id": "/redfish/v1/Managers/1/SnmpService/SNMPAlertDestinations/"
},
"SNMPUsers": {
"#odata.id": "/redfish/v1/Managers/1/SnmpService/SNMPUsers/"
},
"SNMPv1Enabled": false,
"SNMPv3EngineID": "0x8920000000E3028329E002033",
"SNMPv3InformRetryAttempt": 2,
"SNMPv3InformRetryIntervalSeconds": 15,
"Status": {
"State": "Enabled"
},
"TrapCommunities": [
"",
"",
"",
"",
"",
"",
""
],
"TrapSourceHostname": "Manager",
"Users": [
{
"AuthProtocol": "MD5",
"PrivacyProtocol": "DES",
"SecurityName": "",
"UserEngineID": null
},
{
"AuthProtocol": "MD5",
"PrivacyProtocol": "DES",
"SecurityName": "",
"UserEngineID": null
},
{
"AuthProtocol": "SHA",
"PrivacyProtocol": "AES",
"SecurityName": "oneview_4849283d97929392",
"UserEngineID": null
},
{
"AuthProtocol": "MD5",
"PrivacyProtocol": "DES",
"SecurityName": "",
"UserEngineID": null
}
]
}
}
]
I want to select an element in the Users array that has SecurityName set to "" and change that element. I don't need the Comments portion. So, I try to select the section starting with #HpeiLOSnmpService.v2_3_0.HpeiLOSnmpService with:
jq -r '.[] | .#HpeiLOSnmpService.v2_3_0.HpeiLOSnmpService' snmp.json
but it gives me everything without the enclosing array. Anyone have a suggestion?
Thanks!
# starts a comment and your jq program degenerates to .[]|. which is identical to the program .[] (|. is a no-op/the identity filter). This program will simply select all values from the input.
You must quote certain characters, such as #, when they are part of propery names. The following will work with your JSON file:
jq -r '.[] | ."#HpeiLOSnmpService".v2_3_0.HpeiLOSnmpService'
Thanks. Using the quotes around the key with a '#' works. Ultimately, selecting the SecurityName that was unset was done with:
jq -r '.Users[] | select (.SecurityName == "") | {"AuthProtocol":.AuthProtocol,"PrivacyProtocol":.PrivacyProtocol,"SecurityName":.SecurityName,"UserEngineID":.UserEngineID}'

Cuckoo report , meaning of report

'''
{
"category": "process",
"status": 1,
"stacktrace": [],
"api": "CreateThread",
"return_value": 176,
"arguments": {
"thread_identifier": 1228,
"function_address": "0x004021ce",
"flags": 0,
"parameter": "0x0012fef0",
"stack_size": 0
},
"time": 1647881189.051382,
"tid": 1836,
"flags": {}
}
'''
this is part of report of cuckoo,what's the meaning of the "status":1,sometimes it's "status":0.

filtered_search api in freshworks CRM not returning custom attributes

I need data from freshworks CRM rest api and I am using /api/filtered_search/[entity] api to get data modified between 2 time periods. This query is returning correct data. But the result doesn't include all the attributes of a record as the result from view api /api/sales_accounts/view/[view_id]. What should I do to get all attributes of records that are modified between 2 time periods ?
Sample query:
curl -H "Authorization: Token token=XXXXXXX -X POST https://personal-XXXX.myfreshworks.com/crm/sales/api/filtered_search/sales_account?include=owner -d '{ "filter_rule" : [{"attribute" : "updated_at", "operator":"is_in_the_range", "value":["2021-02-10T10:00:00", "2021-02-10T15:00:00"]}] }'
Result:
{
"id": 70000227816,
"name": "Everstage Acc 1",
"last_contacted": null,
"last_contacted_mode": null,
"city": null,
"state": null,
"country": null,
"phone": "1234567890",
"open_deals_amount": "0.0",
"won_deals_amount": "0.0",
"avatar": null,
"created_at": "2021-02-08T22:46:03+05:30",
"updated_at": "2021-02-10T12:31:56+05:30",
"recent_note": null,
"last_contacted_via_sales_activity": null,
"last_contacted_sales_activity_mode": null,
"last_assigned_at": "2021-02-08T22:46:04+05:30",
"facebook": null,
"twitter": null,
"linkedin": null,
"owner_id": 70000012204
}
Expected Result:
{
"id": 70000227816,
"name": "Everstage Acc 1",
"address": "12, abc street, 1st cross, 2nd main",
"city": null,
"state": null,
"zipcode": null,
"country": null,
"number_of_employees": 11,
"annual_revenue": 12,
"website": null,
"owner_id": 70000012204,
"phone": "1234567890",
"open_deals_amount": "0.0",
"open_deals_count": 0,
"won_deals_amount": "0.0",
"won_deals_count": 0,
"last_contacted": null,
"last_contacted_mode": null,
"facebook": null,
"twitter": null,
"linkedin": null,
"links": {
"conversations": "/crm/sales/sales_accounts/70000227816/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3",
"document_associations": "/crm/sales/sales_accounts/70000227816/document_associations",
"notes": "/crm/sales/sales_accounts/70000227816/notes?include=creater",
"tasks": "/crm/sales/sales_accounts/70000227816/tasks?include=creater,owner,updater,targetable,users,task_type",
"appointments": "/crm/sales/sales_accounts/70000227816/appointments?include=creater,owner,updater,targetable,appointment_attendees"
},
"custom_field": {
"cf_customer_succses_email_id": "customer2#abc.com"
},
"created_at": "2021-02-08T22:46:03+05:30",
"updated_at": "2021-02-10T12:31:56+05:30",
"avatar": null,
"parent_sales_account_id": null,
"recent_note": null,
"last_contacted_via_sales_activity": null,
"last_contacted_sales_activity_mode": null,
"completed_sales_sequences": null,
"active_sales_sequences": null,
"last_assigned_at": "2021-02-08T22:46:04+05:30",
"tags": [],
"is_deleted": false,
"team_user_ids": null
}
You can get the list of Sales Account using /api/sales_accounts/view/[view_id] with sort and sort type as updated_at and desc to get the latest updated records. The filtered search API /api/filtered_search/[entity] gives only basic details. Try https://developers.freshsales.io/api/#view_account API for complete attributes per record

error when using Kotlin groupBy function applied to list

I'm very new in Kotlin, and I can't seem to figure out how to do something that is really quite simple; grouping my data by the name field. I've tried with map and groupBy, using one or using both, but I either get an error, or the data is in a list, and the duplicates are filtered out - which I don't want. I need the duplicates grouped.
As an aside, my sql function (in the repository), which finds records in my DB based on the date entered has fields from two different classes, which isn't the optimal way of doing things, but I didn't know how else to combine the data from two tables. I don't mind correcting that if someone can tell me how. The error that I get is "Type inference failed. Expected Type mismatch. Required: List Found Map
String?, List>
below is my code
TIA
my repository code
#Query("SELECT new XXX.report.model.ReportWithBatches(r.adlsPath, r.fileSize, r.lastUpdate, r.remoteFileName, b.dataPath , b.version, b.dataSource, r.recordCount, r.transferStatus, r.businessDate) FROM ReportOutput r INNER JOIN BatchInput b ON r.job.jobUuid = b.reportJob.jobUuid WHERE r.businessDate = ?1")
fun findAllByBusinessDateJoinBatches(date: LocalDate): List<ReportWithBatches>
}
my service code
fun findAllByCreationDateJoinBatches(date: LocalDate): List<ReportWithBatches> {
val reportBatchesList = reportRepository.findAllByBusinessDateJoinBatches(date)
return reportBatchesList.groupBy({it.adlsFullPath}, {it})
// .map { it.value }
// return reportBatchesList
// return reportBatchesList.map { rB ->
// ReportWithBatches(
// rB.adlsFullPath,
// rB.contentLength,
// rB.lastModified,
// rB.remoteFileName,
// rB.dataPath,
// rB.version,
// rB.source,
// rB.numberOfRecords,
// rB.transferStatus,
// rB.creationDate)
//
// }
}
code in my controller
#GetMapping(value = ["/linkBatches/{today}"])
fun findAllByCreationDateJoinBatches(#PathVariable("today") #DateTimeFormat(pattern = "yyyyMMdd") date: LocalDate): List<ReportWithBatches> {
return eligibleService.findAllByCreationDateJoinBatches(date)
}
My result is this - note there's only one batch per record in the result:
[
{
"adlsFullPath": "part-00000-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 20,
"lastModified": "2020-02-07T16:50:16.132-05:00",
"remoteFileName": null,
"dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07"
},
{
"adlsFullPath": "part-00007-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 1104,
"lastModified": "2020-02-07T16:50:16.133-05:00",
"remoteFileName": null,
"dataPath": "preprd/datalake/lake/nes/negotiation/execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07"
},
{
"adlsFullPath": "part-00015-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 1057,
"lastModified": "2020-02-07T16:50:16.133-05:00",
"remoteFileName": null,
"dataPath": "preprd/datalake/lake/nes/negotiation/execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07"
},
]
I would like to get something like this:
[{
"adlsFullPath": "part-00000-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 20,
"lastModified": "2020-02-07T16:50:16.132-05:00",
"remoteFileName": null,
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07",
"batches":{
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=2/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=1/version=1",
"version": 1,
"source": "NETS",
}
},
{
"adlsFullPath": "part-00007-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 1104,
"lastModified": "2020-02-07T16:50:16.133-05:00",
"remoteFileName": null,
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07",
"batches":{
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=2/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=1/version=1",
"version": 1,
"source": "NETS",
}
},
{
"part-00015-1399b2e0-5fa5-484b-91f1-9dec0601b885-c000.csv.gz",
"contentLength": 1104,
"lastModified": "2020-02-07T16:50:16.133-05:00",
"remoteFileName": null,
"numberOfRecords": -1,
"transferStatus": "REPORT_CREATED",
"creationDate": "2020-02-07",
"batches":{
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=3/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=2/version=1",
"version": 1,
"source": "NETS",
},
{ "dataPath": "execution_v1/integration_date=2020-02-07/business_date=2020-02-07/batch_id=1/version=1",
"version": 1,
"source": "NETS",
}
}
}]
Since groupBy returns a Map not a List, you get an error when you do
return reportBatchesList.groupBy({it.adlsFullPath}, {it})
From a function having return type List<ReportWithBatches>. So you will have to change the return type of your function to Map<String, ReportWithBatches> in service.
In your case groupBy will give you a Map which will look something as following
{adlsFullPath1=[Report1, Report2], adlsFullPath2=[Report3]}
For more information read the docs.

Resources