Direct Sharing support for Azure Shared Image Gallery

Resource Provider
CAPS, PIR, CRP
Description of Feature or Work Requested
We now support direct sharing in Azure Shared Image Gallery. The feature allows you to share galleries with other subscriptions and tenants, without having to use Azure RBAC.
Since it's a new way of sharing, we need to make changes in 'az sig', 'az vm create' and 'az vmss create' commands. These are what we had in mind, but we can discuss the design in detail:
Share
Az sig update --permissions "private/groups/community"
Az sig share --subscription-ids "subscription-id" --tenant-ids "tenant-id" --mgmtgrp-ids "managementgroup-ids"
Az sig share --reset? - going from groups to private
List galleries:
Az sig group-list --scope "subscription/tenant/mgmtgrp" --location
List image definition and version:
Az sig image-definition list --scope "subscription/tenant/mgmtgrp/community" --location
Az sig image-version list --scope "subscription/tenant/mgmtgrp/community" --location
Get:
Az sig image-definition show --name "is it gallery name or gallery unique name?"
Minimum API Version Required

Swagger Link
https://github.com/Azure/azure-rest-api-specs/blob/master/specification/compute/resource-manager/Microsoft.Compute/stable/2019-12-01/gallery.json
Target Date
First week of May

Add it to S186.

Could you provide the REST API to the command az sig share ? I don't see the corresponding API and arguments in the swagger file

From @kang in SIG team, swagger file for direct sharing are https://github.com/Azure/azure-rest-api-specs/blob/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-09-30/gallery.json and https://github.com/Azure/azure-rest-api-specs/blob/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-09-30/sharedGallery.json
Arguments are in SharingProfile and SharingUpdate.

Updating Shared Image Gallery commands example
Share

command: gallery update
az sig update --permissions "private/groups "
command: Add sharing id to the sharing profile of a gallery.
  az sig share update --gallery-name "myGalleryName" -g "myResourceGroup" --groups type="Subscriptions" ids="34a4ab42-0d72-47d9-bd1a-aed207386dac" ids="380fd389-260b-41aa-bad9-0a83108c370b" --groups type="AADTenants" ids="c24c76aa-8897-4027-9b03-8f7928b54ff6" --operation-type "Add"
command: reset sharing profile of a gallery.
az sig share update --gallery-name "myGalleryName" -g "myResourceGroup" --operation-type "Reset"

List galleries:

command: List shared galleries by subscription id or tenant id.
az sig group-list --scope " tenant“  --location "myLocation"

List image definition and version:
az sig share image-definition list --gallery-unique-name "galleryUniqueName" --location  "myLocation" –scope "subscription/tenant "
az sig share image-version list --gallery-image-name "myGalleryImageName" --gallery-unique-name "galleryUniqueName" --location "myLocation" --scope "subscription/tenant" –scope "subscription/tenant "
Get:

command: Get a shared gallery by subscription id or tenant id
az sig share image-definition show --gallery-image-name "myGalleryImageName" --gallery-unique-name "galleryUniqueName" --location "myLocation"
Or
az sig share image-definition show –ids “resource id”

Changes
Word 'share' is added in the middle of commands sig image-definition and sig image-definition to avoid influencing existing commands behavior.

Question:
Swagger defined the list API parameter sharedTo to be a single value enum, so --scope can only be set as tenant or None. The designed commands require the option can be set as subscription/tenant
Response from service developer @kangsun-ctrl :

az sig group-list --scope " subscription|tenant“  --location "myLocation"
For list call, in scope, we have subscription and tenant. And the subscription is the default scope, so in backend and swagger, user do not need to specify ‘sharedTo=tenant’ when they just want to list by subscriptionId. And if they want to list by tenant, then they need to specify ‘sharedTo=tenant’.
Just in CLI, we want users to specify subscription or tenant.
For get call, user do not need to specify scope and both subscriptionId and tenantid will be passed in. So we return the result as long as it is shared to user’s tenant or user’s subscription.

Solution:
CLI allows users to set the  --scope option to be subscription/tenant, but if user doesn't set the option or set it to be subscription, cli request the API with sharedTo parameters to be None.
Potential Problem
CLI commands behavior doesn't align with Swagger. So it can not be auto-generated and has to be manually maintained

@kangsun-ctrl
az sig group-list --scope tenant will cause a error:
# Request URL: 'https://management.azure.com/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/providers/Microsoft.Compute/locations/eastus/sharedGalleries?api-version=2020-09-30&sharedTo=tenant'

"error": {
  "code": "InternalOperationError",
  "message": "Getting dht entry '54826b22-38d6-4fb2-bad9-b7b93a3e9c5a' from dht table 'TenantSharingDHT' failed using CrpPir Client"
}

This error message will be really confusing for customers, user-friendlier notes would be much better

@xfz11 if we restrict az sig group-list --scope tenant to only 'tenant', will there still be an issue? How difficult is it to manually maintain?

It seems that mgmtgrp/community scope will be supported in the future, then CLI developers should add them manually. But if we align with Swagger, setting --scope to be only tenant as Swagger defined, then we can use codegen tool to automatically generate code.
For this feature, manual maintaining will not cost much efforts. But it a trend to embrace codegen since maintaining all tremendous commands manually will be not realistic with the growing number of feature requests.

@xfz11 if we restrict az sig group-list --scope tenant to only 'tenant', will there still be an issue? How difficult is it to manually maintain?

It seems that mgmtgrp/community scope will be supported in the future, then CLI developers should add them manually. But if we align with Swagger, setting --scope to be only tenant as Swagger defined, then we can use codegen tool to automatically generate code.
For this feature, manual maintaining will not cost much efforts. But it a trend to embrace codegen since maintaining all tremendous commands manually will be not realistic with the growing number of feature requests.

@xfz11  Actually I think if you will do it manually, then it is better to map scope=subscription to swagger with no sharedTo option, and map scope=tenant to swagger with sharedTo=tenant. It will be more clear for customer. Codegen is cool, we will keep it in mind and try to align our future development with CLI Codegen.

@kangsun-ctrl Of course we can manually add the commands if you persist, I just raise the potential problem for discussion.
Actually the key point is that present Swagger may be not clear enough to let users know what will happen calling the API. sharedTo is just described as  The query parameter to decide what shared galleries to fetch when doing listing operations. and defined as a single value enum. Users will be not sure how to request by 'subscription' or what will happen if sharedTo is set to be None.
I still think it is necessary to update Swagger now or later. Add subscription as the enum value as it is.  And you can use default data field to specify the default value. That would make more sense.

@kangsun-ctrl I'm not sure what you mean by design the command to be 'share list --scope'. It seems that the command will share a list within the scope. But in fact, you just want to list the galleries instead of sharing.
Your advice is still helpful, maybe we should reconsider the commands design to make it more consistent and approachable. But it would be risky to catch next CLI release.

Since it may confuse customers that list command contains a verb 'share', I'd like to change command
az sig share image-definition list/show, az sig share image-version list/show
to
az sig shared-image-definition list/show, az sig shared-image-version list/show
Then the commands would be more approachable.
@kangsun-ctrl @olayemio  What do you think of the changes?

Since it may confuse customers that list command contains a verb 'share', I'd like to change command
az sig share image-definition list/show, az sig share image-version list/show
to
az sig shared-image-definition list/show, az sig shared-image-version list/show
Then the commands would be more approachable.
@kangsun-ctrl @olayemio What do you think of the changes?

This is a good point. I like this idea since our backend resource is 'Gallery'/'SharedGallery'

Hi @xfz11 and @kangsun-ctrl , my proposal would be
az sig image-definition --scope "subscription" --region "eastus list/show"
I don't want customers to look at the API and think shared-image-definition and image-definition are different resources.

Hi @xfz11 and @kangsun-ctrl , my proposal would be
az sig image-definition --scope "subscription" --region "eastus list/show"
I don't want customers to look at the API and think shared-image-definition and image-definition are different resources.

Hi @olayemio , if we use image-definition, then parameters are not the same actually. To use normal gallery, user needs to pass '- galleryName', and to use sharedGallery, user needs to pass '- galleryUniqueName'. GalleryUniqueName = subscriptionId + galleryName. So that would be
az sig image-definition
[--gallery-unique-name string]
[--gallery-name string]
[--gallery-image-name]
[--location ]
And that might get user confused. Because they do not know when to pass in galleryName and galleryUniqueName.

@kangsun-ctrl
here's my thought process:

The resources are actually the same. shared-image-definition and image-definition raises confusion that they are two completely separate resources
Whether we use shared-image-definition or only use image-definition, a customer will always have to know which one to use.

@kangsun-ctrl
here's my thought process:

The resources are actually the same. shared-image-definition and image-definition raises confusion that they are two completely separate resources
Whether we use shared-image-definition or only use image-definition, a customer will always have to know which one to use.

Hi @olayemio , actually the resources are not the same. normall gallery comes from Caps, and sharedGallery comes from CrpPir, which means that their api models are different too. For example, normal gallery image version contains "publishingProfile - publishedData" while shared gallery image version contains "properties -publishedDate". Given user will actually have different experience using those two, spliting them might be a good idea.
Another concern from me is that galleryName looks confusing when we have another option called 'galleryUniqueName'

Hi @xfz11, after internal discussions, we are making changes to the list galleries, image definitions and image versions calls
List galleries:
az sig list-in-group  --group "subscription" --region "eastus"
List image definition and version:
az sig image-definition list-in-group/show-in-group --group "subscription" --region "eastus" --gallery-unique-name ...
az sig image-version list-in-group/show-in-group --group "subscription" --region "eastus" --gallery-unique-name ...
we have an additional question:

if I log into two tenants, is there a way for CLI to pass the current tenant to our API. Also if a customer wants to switch their current tenant, how would they do that?

Hi @olayemio, why is the option --location "eastus" changed to  --region "eastus"
In CLI command, it is all defined as location.

Hi @olayemio @kangsun-ctrl , we discussed the changes in CLI team, and we think the verb list-in-group/show-in-group doesn't conform to CLI convention. If you insist on changing the commands, we can discuss it later. But tomorrow CLI will stop merge PR for next release. Please contact @Juliehzl for following discussion about the feature.
Thanks

@xfz11 sorry for the confusion, I meant "location", not "region". Can you explain why list-in-group/show-in-group does not conform to CLI convention.
New changes
List galleries:
az sig list-in-group  --group "subscription" --location "eastus"
List image definition and version:
az sig image-definition list-in-group/show-in-group --group "subscription" --location "eastus" --gallery-unique-name ...
az sig image-version list-in-group/show-in-group --group "subscription" --location "eastus" --gallery-unique-name ...

Hi @olayemio, CLI Command is composed of az [resource name] [operation] [option], generally the common operation is named create/update/list/show and we can use option to restrict the operation type or scope.
So the command should either be az sig image-definition list --type gallery/sharedGallery or  az sig shared-image-definition list
As @kangsun-ctrl mentioned above, the former command will confuse users. Because the command az sig image-definition list require users to pass different options, such as galleryUniqueName and galleryName.
So we think the latter will conform to CLI convention better.
Based on Swagger and context provided by service developer, we think shared-image-definition and image-definition are not absolutely the same resource . @kangsun-ctrl says that the image shared by direct sharing doesn't belong to the shared user. But if users use original way to share gallery/image, then image will belong to shared user.
So we use the qualifier shared- to separate 2 kinds of resource.
If you don't agree with current command design, we will not merge the PR to catch CLI 5/25 release. @Juliehzl will support you later.

@xfz11 our preference is to stick with list-in-group / show-in-group. I see that az vm assess-patches, az vm availability-set list-sizes, az vm boot-diagnostics get-boot-log-uris break the CLI convention as well. For a great customer experience, we need to break the convention as well for this feature.
and to clarify, the resources are the same. It's just the mode of sharing that is different. There is RBAC (user, group, service principal) and now direct sharing (subscription or tenant) for the same resource.
We'll work with @Juliehzl


Closes #5764

Closes #5764
✅ Pull Request Checklist:

[ ] Included link to corresponding React Spectrum GitHub Issue.
[ ] Added/updated unit tests and storybook for this change (for new code or code which already has tests).
[ ] Filled out test instructions.
[ ] Updated documentation (if it already exists for this component).
[ ] Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

Closing as a duplicate of https://github.com/adobe/react-spectrum/pull/5783


Problems with astroturf in nextjs

I am currently working on redoing my personal website as a nextjs app and decided to try astroturf but I keep getting this error:

I don't quite know what is causing this to happen, but the workaround I found is to go into the index.js in my IDE and resave it. After that the error usually doesn't re-appear again until I restart the dev server. Obviously this will become problematic as I begin to style components.
For reference I played around with both stylesheet and the css prop.
Here's my nextjs config:
// next.config.js
module.exports = () => ({
  webpack: config => {
    config.module.rules.push({
      test: /\.js$/,
      use: ["astroturf/loader"]
    });

    return config;
  },
  trailingSlash: true,
  reactStrictMode: true,
  poweredByHeader: false,
  future: { webpack5: true }
});

I'm hitting the same error randomly but so far haven't been able to isolate a minimal reproduction case that makes it trigger consistently (sometimes I'll restart the dev server and it's fine, sometimes it'll explode like in your case).
I think, as noted in #681, that Astroturf isn't really compatible with Webpack 5 unless you set options: { useAltLoader: true } in the loader configuration. What's confusing is that it seems to sometimes work without this setting. It might be better if Astroturf simply threw an error (or defaulted to useAltLoader) if it detected it was running under Webpack 5?

I will try the altLoader and see if that works for me (I'm intending to mostly just use a single stylesheet per component and postcss plugins instead of inserting any variables, so I might be able to just get away with it for now), if not I'll just have to use css modules for now and port everything to astroturf in the future.

astroturf should work without the altLoader but only if the persistent cache is off.

I'm assuming persistent cache is turned on in nextjs by default? I haven't changed anything other than the config I included above, not sure what nextjs' defaults are like (and why) as this is my first time using it.
Here's my updated next config for reference:
// next.config.js
module.exports = () => ({
  webpack: config => {
    config.module.rules.push({
      test: /\.js$/,
      use: [
        {
          loader: "astroturf/loader",
          options: {
            useAltLoader: true
          }
        }
      ]
    });

    return config;
  },
  trailingSlash: true,
  reactStrictMode: true,
  poweredByHeader: false,
  future: { webpack5: true }
});

I tried starting the dev server a few times (incl. deleting the ./.next folder inbetween) and have not gotten the error message again, so assuming I don't run into new issues with the altLoader my problem is fixed for now :)

Why is there no official next.js example in the atstroturf docs? There is a link but it is broken...

Personally I stopped using Astroturf back in 2021... there were too many tooling issues that weren't getting fixed. The death knell for me was when Next removed their Astroturf example from the Next repo, even though they maintain hundreds of other tool and library examples. It just wasn't worth to try to wrestle with something that was becoming a more and more marginal solution.
For what it's worth I've been having a very good time with Tailwind, which to me offers a very similar experience of writing isolated styles colocated with your code. As of Tailwind 3 it supports completely arbitrary properties, which means there's almost never a need to reach for external CSS. If you need reusable styles, you can just assign a string of Tailwind classnames to a variable, export it, and use it as any React component's className (or interpolate it into a template literal), exactly like you'd do with Astroturf. It's got really excellent support across frameworks and great tooling (including a super good VS Code plugin).
Hope that helps!

Hey folks, originally Next was just webpack and css-loader so there weren't any specific Next specific details to using astroturf, you configure the loader like any other webpack loader and it should Just Work. Over the years tho it seems that next vendored and somewhat forked css-loader which makes it really hard to keep up with, especially since I don't ever use Next.
Ultimately it should generally just work using the loader, but because I'm not an active user of Next it's hard to say what might be broken or missing. Webpack as a tool is absurdly complex now, and Next (and any other framework) add whole new levels of abstraction on top of them, that makes it very hard for me to keep up to date, not to mention needing to support Vite, rollup, parcel, etc.
I am always happy to update docs tho if folks with experience want to contribute, but i also realize that diving deep into webpack and Next internals isn't fun (heck that's partly why I haven't, webpack alone is enough). And if bundler specific plugin isn't working the simplest thing to do (if you want to use astroturf) is just to use the babel plugin directly.

@lostfictions & @jquense - thanks for your insights! At our company we're doing a discovery week for "CSS-in-JS" solutions and so we stumbled upon astroturf... that's whay i tried to get it working with next.js. But yeah, i totally understand how hard it must be to keep up with the developments from next/css-loader and webpack. We generally think that astroturf is doing an extremely great job internally, by not using any runtime (that's what we're seeking for regarding the new streaming of react 18 - like everyone is fighting right now who has a styled-component stack as we do)
But unfortunately, it seems like astroturf never gained a lot of traction in the market - right now we're sticking with styled-components and hopefully they get their problems fixed with v6
Personally, i love tailwind and i'm also using it for all my new projects :)

I will add that I've use/used astroturf in a number of high stakes production apps, and can attest that it's a solid choice, even if it's not a fan favorite. If you want another compile time styling alternative there is linaria and vanilla extract which are both good if not philosophically distinct from astroturf
(I also use and like tailwind, I think it's more of a complementary tech than replacement tho)

Closing this as I'm no longer using Next and it seemingly either was never supported properly or just works now. The section in the docs just says "see example" with a broken link to the same page.


[com.google.fonts/check/varfont/wdth_valid_range] The check is more strict than the OT spec

Observed behaviour
The check Fails when a font has an instance with a wdth value greater than 1000. but the spec says the following:

Valid numeric range: Values must be strictly greater than zero.
https://learn.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wdth

This is why I’m getting on the report:

The variable font 'wdth' (Width) axis coordinate must be within spec range of 1 to 1000 on all instances.
Check ID: FontBakeryCheck:com.google.fonts/check/varfont/wdth_valid_range
According to the Open-Type spec's registered design-variation tag 'wdth' available at https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wdth
On the 'wdth' (Width) axis, the valid coordinate range is 1-1000
🔥 /MyFont-VF.ttf
🔥 FAIL Found a bad "wdth" coordinate with value 1270.0 outside of the valid range from 1 to 1000. [code: wdth-out-of-range]

closed by #4002

Thanks!


[CT-652] dbt-docs Improvements

This issue is a collection of all of the possible bug fixes and/or enhancements in dbt-docs.  There will be a single new index file including all of these changes.

[ ] Use column.comment from catalog/database if column.description is missing
[ ] Fix the sample SQL when the source has no database
[ ] Improved Searching
[ ] [Snyk] Upgrade prismjs from 1.27.0 to 1.28.0
[ ] Adds support for File selector matcher
[ ] many dependabot suggestions that need validation

Note: The related PR should have a changie file for each PR below giving credit to the appropriate contributor but ref this issue.

@jtcohen6 Would love some direction on what should be slated for 1.1.1 and what should wait on 1.2?
None are currently merged in.

@emmyoop I think 1.2 is fair for all of these. They're valuable net improvements, and none makes the dbt-docs site unusable in its current state.


COOPR-615: Enable kerberos login for zookeeper.

@jwang47 Added kerberos login to secure communications with ZooKeeper.
I have tested the fix locally and as result got next messages in ZooKeeper:
2014-12-18 18:39:33,649 [myid] - INFO  [NIOServerCxn.Factory:<IP_ADDRESS>/<IP_ADDRESS>:2181:NIOServerCnxnFactory@197] - Accepted socket connection from /<IP_ADDRESS>:52630
Found key for zookeeper/example.com@EXAMPLE.COM(23)
Found key for zookeeper/example.com@EXAMPLE.COM(16)
Found key for zookeeper/example.com@EXAMPLE.COM(1)
2014-12-18 18:39:33,651 [myid] - INFO  [NIOServerCxn.Factory:<IP_ADDRESS>/<IP_ADDRESS>:2181:ZooKeeperServer@868] - Client attempting to establish new session at /<IP_ADDRESS>:52630
2014-12-18 18:39:33,662 [myid] - INFO  [SyncThread:0:ZooKeeperServer@617] - Established session 0x14a5e3c7ff40001 with negotiated timeout 40000 for client /<IP_ADDRESS>:52630
The cdap-security will be replaced by common-security, when this refactoring will done.

LGTM


Support branching from a release branch

It's fairly rare in Release Flow that you would make a change by branching from somewhere other than the trunk branch (usually main). But occasionally there are changes that you need to release, but that don't need to exist on main. From the Microsoft docs:

The only exception, of course, is when the change doesn’t make sense to bring into master. Perhaps there’s been some refactoring that means that this bug doesn’t exist in master anymore. That’s the only time pull requests can go directly into a release branch without going through master first.

Currently, for version calculation purposes, the library assumes that a working branch (as specified in the config file by one of the workingBranchPrefixes) always branches from the trunk.
This issue is to find a way to support the unusual use case of branching from a release branch. I haven't yet decided on an algorithm that will identify the correct release branch - probably it will have to be via a naming convention. Suggestions welcome!

Great initiative. Our company is adapting release flow and I am looking at ways to generate accurate build and asset numbers, automated. We have been relying on counters and variables of Azure devops which are too constrained.
I have looked into GitVersion but I am having trouble to set it up correctly for Release Flow. I managed to get weird versioning by, well branching randomly:)
i will have a deeper look at your library, formulate some testcases. And I do plan to llok into the code.
The limitation to not allow hotfixes from release branches, is for our usecase, an issue. We need to support multiple versions of out product so hotfixes in master inly do not work.
Also, I wonder how your library tags PRs. From refs/pull/… while not mentioned in the ReleaseFlow documentation, here a tagging that considers the PR number just makes so much sense.
But a question upfront. Do you have a description of the current versioning algorithm. That would allow me to more quickly get into the topic, instead of reading code :)
kind regards and thanks again
mark

Hi @mmunte-impeo thanks for contributing, and apologies for not replying sooner - it's a holiday weekend here in the UK, and I've been away from my computer for a day or so.
The first comment I'd make is that Release Flow is not really designed for a scenario where you need to support multiple software versions - so, if you decide to use it, you might find that you hit a few challenges over and above simply tooling support.
That said, I'd love to see if we can add support for your use case without overcomplicating it for the 95%. Like you, I started by trying to persuade GitVersion to do what I wanted, and I ended up writing this library because I couldn't.
The versioning algorithm is largely contained within BuildVersionCalculator.ts although it uses the strategy pattern to abstract any behavioural differences between SemVer and Milestone variants - these are described in the README.
In summary, the algorithm works like this:

Determine the build context based on the current commit, current branch, target branch. This process identifies the version source and a prerelease label, if appropriate. For PR builds (to answer your question), the prerelease label is something like pr.1234 - see here.
Increment the version number by using the configured strategy.
Count the number of commits between the version source and the current commit (which is useful for generating a unique build number).

These values are all used to generate the build version number.
Having just re-read the code, it already handles PRs that target a release branch, to support cherry-picking from a hotfix branch from main onto a release branch. So this might support your use case as well, in which case I can update the documentation. I suggest you create a test repo where you can try this stuff out for your own scenarios - please let me know how you get on!

Hey. Thx for the reply. I did indeed look at the sources to also see dependencies on other libs and was happy to find there is nothing exotic in there. And yes, I am proficient in Typescript.
Your code is really well organized. Kudos.
In a test repo, playing a bit, I was able to quickly generate double version numbers on the same feature branch, by merging into it again, afterwards.
I have a suggestion: i realized that I myself have to clear view yet on how I would like the versioning to behave. Especially how it shall behave on more challenging merge scenarios. Without this clarity it is pointless to even try to implement anything:). So I will try to document scenarios and how I believe the behavior should be. Happy to then compare and discuss with you. Then we can see if it is changes (and corrections) to the SemVer strategy or maybe a mew one.
I will come back as soon as I have something.

Sounds good, and thanks for trying out some scenarios. Thinking back, the reason I copped out of support for this was partly because I couldn't imagine the use cases. That, plus I didn't need to! So I'm glad you're able to think it through with some practical examples, and grateful for your help. I look forward to hearing your suggestions 😃


fix(Calendar): sometimes first day of next month is missing

When fixedWeeks is true and next month starts in another row of Calendar first day was missing:

After the fix:

Fix is quite simple but I've also extended the test case and added a new story for fixedWeeks.
I do not know if you want to have all fixes covered by a test case but taking in to account that on my machine Calendar tests took 15 seconds before and now 2 seconds were added I would personally not merge my test.
I think the new story is also not providing that much value but it helped me test the fix so I included it as well.
Thank you for this library and for shadcn/vue :)

Great catch @xollaborator! Thank you for your contribution!👍🏻
This functionality and the date utilities are ported from Melt UI, therefore this fix would help them too.
Here's the corresponding line in Melt UI: https://github.com/melt-ui/melt-ui/blob/42e2dd430c3e13f56062c4d610dabd84ea4e5517/src/lib/internal/helpers/date/calendar.ts#L97

This functionality and the date utilities are ported from Melt UI, therefore this fix would help them too.

Sure, I might try to help them, especially that there is already bug for this issue: https://github.com/melt-ui/melt-ui/issues/1213.


Replace usage of socketpair for IPC

On Windows, using a socket as standard input file descriptor is daring. Even if it may be possible, Lwt will currently outright reject it. We can, instead of passing a file descriptor to the spawned process, pass the address of the UNIX domain socket as an argument so that the sub process may open a socket itself and connect to that address.
UNIX domain sockets are supported on Windows 10 and OCaml 4.14.

The CI failure will be fixed by #24 .

LGTM. Just a question why not having ocaml >= 4.14.0 for solver-service-api too ?

Well strictly speaking it's the other packages that require 4.14 for Unix domain sockets on Windows, but yeah I can add it everywhere.

Having an ocaml 4.14 constraint should fix the CI issue.
Both places we want to use this will also be OCaml 4.14 or newer.


Pls,Support push notification for event call when Application is close / on background.

I hope that, connectycube-flutter lib, will be support call method when application on close or background for Android and IOS.

Yes, we plan to add background calls support in one of near release.

Yeahhhh, I love U 3000 <3

+1 for this awesome feature as this is essential for each VoiP App :)

Is there a way to implement this with the current API? With a background process with the workmanager plugin perhaps?

hello guys, we updated our Push Notifications documentation  for Flutter. You can try use it to implement Push notifications to your Flutter projects before we implement it in our sample.

I am trying to use Push notification for Android however, it is not working as expected.
code sample:

Result:

Notification: title and body should not be null. How can I set these values?
Also, I do not get any notification on device. Though message is getting captured in debug console.
If I send dummy message from FCM console, my device do get alert but not from Connectycube 'Push Notifications'-> 'Send' console.

@shivanijha002

Notification: title and body should not be null. How can I set these values?

For the Android platform, you have to set them to the parameters map, for iOS you can use some additional parameter from our API. Note: ConnectyCube server always sends GCM with 'data' type, not 'notification'.

Also, I do not get any notification on device. Though message is getting captured in debug console.

For Android, it is expected behavior. You have to do it yourself. For example, you can use flutter_local_notifications plugin for it.
For iOS, it is a system feature and the system does it instead of you.

@shivanijha002

Notification: title and body should not be null. How can I set these values?

For the Android platform, you have to set them to the parameters map, for iOS you can use some additional parameter from our API. Note: ConnectyCube server always sends GCM with 'data' type, not 'notification'.

Also, I do not get any notification on device. Though message is getting captured in debug console.

For Android, it is expected behavior. You have to do it yourself. For example, you can use flutter_local_notifications plugin for it.
For iOS, it is a system feature and the system does it instead of you.

Thank you for the details. It might be useful if you can add it in your documentation. I wasted 2 days trying out different things and hoping it will work without anything external.
flutter_local_notifications has worked for me on Android.

@shivanijha002

Notification: title and body should not be null. How can I set these values?

For the Android platform, you have to set them to the parameters map, for iOS you can use some additional parameter from our API. Note: ConnectyCube server always sends GCM with 'data' type, not 'notification'.

Also, I do not get any notification on device. Though message is getting captured in debug console.

For Android, it is expected behavior. You have to do it yourself. For example, you can use flutter_local_notifications plugin for it.
For iOS, it is a system feature and the system does it instead of you.

Thank you for the details. It might be useful if you can add it in your documentation. I wasted 2 days trying out different things and hoping it will work without anything external.
flutter_local_notifications has worked for me on Android.

@shivanijha002
Please, give me suggestion how to get notification using  flutter_local_notifications for Push notification.
I got below error:
 Invalid argument(s): Failed to setup background message handler! `onBackgroundMessage`
 should be a TOP-LEVEL OR STATIC FUNCTION and should NOT be tied to a
 class or an anonymous function.

Hello @TatankaConCube

How to get pushToken in push notification for subscription?

parameters.pushToken = "2b6f0cc9...4b831186";

push token is static or dynamic?

deviceId is static or dynamic and also how can I get It?

I store device is this way using device_info: ^0.4.2+9 package.
Future<String> _getId() async {
    var deviceInfo = DeviceInfoPlugin();
    if (Platform.isIOS) {
      // import 'dart:io'
      var iosDeviceInfo = await deviceInfo.iosInfo;
      return iosDeviceInfo.identifierForVendor; // unique ID on iOS
    } else {
      var androidDeviceInfo = await deviceInfo.androidInfo;
      });
      return androidDeviceInfo.androidId; // unique ID on Android
    }
  }

Is this right way or I have to implement other method?

When I send notification It registerd on dashboard but it displays in falied status.

So, help me to solve this issue.

How to get pushToken in subscription for push notification?

you have to use flutter plugins for this, in our documentation, we provided the needed code for this.

push token is static or dynamic?

it can be changed during the app work, please, see our documentation, how to get the current token, and how to subscribe to its changes.

deviceId is static or dynamic and also how can I get It?

it is a static unique identifier for your device on the ConnectyCube server. You provided the correct code for getting it.

When I send notification It registerd on dashboard but it displays in falied status.

need more details about this issue:

which error present in failed log?
have some receivers subscription in the Connectycube admin panel?
for which platform (Android or iOS) do you send notification?
how you send notification (via API from app or from Admin panel)?

- which error present in failed log?
W/System.err( 4415): java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.ClipData.getItemCount()' on a null object reference
W/System.err( 4415):    at android.os.Parcel.readException(Parcel.java:1626)
W/System.err( 4415):    at android.os.Parcel.readException(Parcel.java:1573)
W/System.err( 4415):    at android.content.IClipboard$Stub$Proxy.getPrimaryClip(IClipboard.java:197)
W/System.err( 4415):    at android.content.ClipboardManager.getPrimaryClip(ClipboardManager.java:247)
W/System.err( 4415):    at io.flutter.plugin.platform.PlatformPlugin.getClipboardData(PlatformPlugin.java:283)
W/System.err( 4415):    at io.flutter.plugin.platform.PlatformPlugin.access$700(PlatformPlugin.java:24)
W/System.err( 4415):    at io.flutter.plugin.platform.PlatformPlugin$1.getClipboardData(PlatformPlugin.java:82)
W/System.err( 4415):    at io.flutter.embedding.engine.systemchannels.PlatformChannel$1.onMethodCall(PlatformChannel.java:141)
W/System.err( 4415):    at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
W/System.err( 4415):    at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
W/System.err( 4415):    at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:692)
W/System.err( 4415):    at android.os.MessageQueue.nativePollOnce(Native Method)
W/System.err( 4415):    at android.os.MessageQueue.next(MessageQueue.java:323)
W/System.err( 4415):    at android.os.Looper.loop(Looper.java:143)
W/System.err( 4415):    at android.app.ActivityThread.main(ActivityThread.java:7224)
W/System.err( 4415):    at java.lang.reflect.Method.invoke(Native Method)
W/System.err( 4415):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
W/System.err( 4415):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Failed notification log :
{"notification":{"id":6382549,"badge":null,"device_token":null,"sound":"default","alert":null,"data":{"message":"jhfgjhbn","custom_parameter1":"FLUTTER_NOTIFICATION_CLICK","custom_parameter2":"custom parameter value 2","collapse_key":"event3072823"},"expiry":86400,"delivered":false,"delivered_at":null,"failed":true,"failed_at":"2020-10-22T09:16:38+00:00","fail_after":"2020-10-22T10:16:32+00:00","retries":0,"error_code":null,"error_description":"Unable to deliver notification 6382549, received error (Failed to deliver to all recipients. Errors: InvalidRegistration.)","deliver_after":null,"alert_is_json":null,"app_id":1246,"collapse_key":null,"delay_while_idle":false,"registration_ids":["2206393...2206393"],"uri":null,"priority":10,"url_args":null,"category":null,"content_available":false,"mutable_content":false,"notification":null,"type":"Rpush::Client::Redis::Gcm::Notification","event_id":3072823,"event_date":"2020-10-22T09:16:31+00:00"},"log":[{"device_token":null,"delivered_at":null,"failed_at":"2020-10-22T09:16:38+00:00","error_code":null,"error_description":"Unable to deliver notification 6382549, received error (Failed to deliver to all recipients. Errors: InvalidRegistration.)"}]}
- have some receivers subscription in the Connectycube admin panel?
Yes.

- for which platform (Android or iOS) do you send notification?
Android
- how you send notification (via API from app or from Admin panel)?
I follow step to integrate notification.
I want to send send using firebase with your dashboard.

Hello @TatankaConCube
I want to use notification functionality in chat application. I implemented this functionality using your connectycube_sdk package. I follow each and every steps to do this functionality and also I successfully implemented this functionality. But in this code I face one issue is that when user is offline or not in the dialog page I can't get notification. In terminal there is no any error display. Every API from your server is called successfully and it displays log of generated notification. When I push on send button notification generates which displays in connecty_cube dashboard. Also device is registered in Push Notification -> Device subscription panel. Every notification displays in Push Notification -> Queue panel. but in this panel Start date, End date, Period are not displayed. When I click on status I get this issue in log received error (Failed to deliver to all recipients. Errors: InvalidRegistration). So I can't get receiver for notification. Please help me to solve this issue asap. I also displays image in above comment. Please check it.

There are descriptions of possible errors on sending push notifications from Connectycube server to FCM. Looks like you have the wrong (or expired) token in the subscription. Try delete the subscription from the admin panel and create a new one, then try to send push notification again.

There are descriptions of possible errors on sending push notifications from Connectycube server to FCM. Looks like you have the wrong (or expired) token in the subscription. Try delete the subscription from the admin panel and create a new one, then try to send push notification again.

Hello @TatankaConCube
Please check log which is updated in above comment.

And you get the same error again? Right?

And you get the same error again? Right?

Yes

Did you configure the required tokens in the ConnectyCube admin console? Did you add google-services.json file to your Android project?

Did you configure the required tokens in the ConnectyCube admin console? Did you add google-services.json file to your Android project?

Yes, I configure all require token in ConnectyCube admin console.

Yes, I add google-services.json file in Android Project.

This is my google-services.json file.
{
  "project_info": {
    "project_number": "948024062720",
    "firebase_url": "https://chatconnectycube-b3b85.firebaseio.com",
    "project_id": "chatconnectycube-b3b85",
    "storage_bucket": "chatconnectycube-b3b85.appspot.com"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:948024062720:android:f14a8bcb7bc30bb09eb9e5",
        "android_client_info": {
          "package_name": "com.example.chatconnectycubesdk"
        }
      },
      "oauth_client": [
        {
          "client_id": "948024062720-9le85u800fbqtd1gkbrmpv584bg20mvt.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.example.chatconnectycubesdk",
            "certificate_hash": "b81d0c07036f1cbdc7e4483e8cba343f80ca4682"
          }
        },
        {
          "client_id": "948024062720-bjjnaig93fjasb7qctjgf3ftphum6cdb.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyBAKCSyeIhx-li2zBz4HOdF4xirAaoAyFY"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "948024062720-bjjnaig93fjasb7qctjgf3ftphum6cdb.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    }
  ],
  "configuration_version": "1"
}

@TatankaConCube

hmm, it is strange (((
can you try to use another plugin for getting a token from the Android system?

hmm, it is strange (((
can you try to use another plugin for getting a token from the Android system?

I get device Id using device_info plugin.
This way I get deviceId

String dId = '';

  Future<String> _getId() async {
    var deviceInfo = DeviceInfoPlugin();
    if (Platform.isIOS) {
      // import 'dart:io'
      var iosDeviceInfo = await deviceInfo.iosInfo;
      setState(() {
        dId = iosDeviceInfo.identifierForVendor;
        print('IOS:::::::' + dId);
      });
      return iosDeviceInfo.identifierForVendor; // unique ID on iOS
    } else {
      var androidDeviceInfo = await deviceInfo.androidInfo;
      setState(() {
        dId = androidDeviceInfo.androidId;
        print('Android:::::::' + dId);
      });
      return androidDeviceInfo.androidId; // unique ID on Android
    }
  }

This is subscription() method snippet which call message send time.

Future<void> subScription() async {
    bool isProduction = bool.fromEnvironment('dart.vm.product');

    CreateSubscriptionParameters parameters = CreateSubscriptionParameters();
    parameters.environment =
        isProduction ? CubeEnvironment.PRODUCTION : CubeEnvironment.DEVELOPMENT;

    if (Platform.isAndroid) {
      parameters.channel = NotificationsChannels.GCM;
      parameters.platform = CubePlatform.ANDROID;
    } else if (Platform.isIOS) {
      parameters.channel = NotificationsChannels.APNS;
      parameters.platform = CubePlatform.IOS;
    }

    String token = await _fcm.getToken();

    String deviceId = dId;
    parameters.udid = deviceId;
    print(
        'pushToken======/*$token*/ ${_cubeDialog.getRecipientId()}...${_cubeDialog.userId}');
    parameters.pushToken =
        '${_cubeDialog.getRecipientId()}...${_cubeDialog.userId}'; /*"2b6f0cc9...4b831186";*/
    parameters.bundleIdentifier =
        "";

    createSubscription(parameters.getRequestParameters())
        .then((cubeSubscription) {
      print('SUBSCRIPTION SUCCESS ====> $cubeSubscription');
    }).catchError((error) {
      print('SUBSCRIPTION ERROR ==> $error');
    });
  }

This is my sendNotification()  method

void sendPushNotification() {
    bool isProduction = bool.fromEnvironment('dart.vm.product');
    CreateEventParams params = CreateEventParams();
    params.parameters = {
      'message': 'jhfgjhbn',
      // 'message' field is required"Some message in push"
      'custom_parameter1': 'FLUTTER_NOTIFICATION_CLICK',
      //"custom parameter value 1"
      'custom_parameter2': "custom parameter value 2",
      'ios_voip': 1
      // to send VoIP push notification to iOS
      //more standard parameters you can found by link https://developers.connectycube.com/server/push_notifications?id=universal-push-notifications
    };

    params.notificationType = NotificationType.PUSH;
    params.environment =
        isProduction ? CubeEnvironment.PRODUCTION : CubeEnvironment.DEVELOPMENT;
    params.usersIds = [_cubeDialog.userId, _cubeDialog.getRecipientId()];

    createEvent(params.getEventForRequest()).then((cubeEvent) {
      print('CUBE EVENT -----> $cubeEvent');
    }).catchError((error) {
      print('CUBE EVENT ERROR -----> $error');
    });
  }

This is getToken() method

void getToken() {
   final connector = createPushConnector();
   if (connector.token.value != null) {
     String token = connector.token.value;
     print('Exist token: $token');
   } else {
     connector.token.addListener(() {
       String token = connector.token.value;
       print('Updated token: $token');
     });
   }
 }

This is init() method

void init() async {
final connector = createPushConnector();
connector.configure(
    onLaunch: onLaunch,
    onMessage: onMessage,
    onResume: onResume,
    onBackgroundMessage: onBackgroundMessage);

connector.requestNotificationPermissions();

getToken();

}

// Called when your app launched by PushNotifications
Future onLaunch(Map<String, dynamic> message) {
log('onLaunch, message: $message');
return Future.value();
}
// Called when your app become foreground from background by PushNotifications
Future onResume(Map<String, dynamic> message) {
log('onResume, message: $message');
return Future.value();
}
// Called when receive PushNotifications during your app is on foreground
Future onMessage(Map<String, dynamic> message) {
log('onMessage, message: $message');
return Future.value();
}
// Called when receive PushNotifications when app was stopped (Android only).
static Future onBackgroundMessage(Map<String, dynamic> message) {
log('onBackgroundMessage, message: $message');
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
}
if (message.containsKey('notification')) {
  // Handle notification message
  final dynamic notification = message['notification'];
}

// Or do other work.
return Future.value();

}
This is the code snippet which I use for notification. If I made any mistake then Please suggest me asap. @TatankaConCube

Yes, sure, it is the main problem. But I do not understand, which token you used before for creating a subscription?
Which version of flutter_apns plugin do you use? or just from GitHub like in our documentation?

flutter_apns plugin depends on firebase_messaging plugin, please read its Readme and add needed configs to your project.

@TatankaConCube

Yes, sure, it is the main problem. But I do not understand, which token you used before for creating a subscription?

I use this method for getting token
if (connector.token.value != null) {
    String token = connector.token.value;
    log('Exist token: $token');
  } else {
    connector.token.addListener(() {
      String token = connector.token.value;
      log('Updated token: $token');
    });
  }

Which version of flutter_apns plugin do you use? or just from GitHub like in our documentation?

I use flutter_apns: ^1.3.1.

flutter_apns plugin depends on firebase_messaging plugin, please read its Readme and add needed configs to your project.

Dear @TatankaConCube
I already done all this requirement. I have only one confusion for this this plugin. Should I have to mention below method which is given in firebase_messaging documentation?
firebase_messaging

I can't get token in getToken() method.

how you created subscriptions before without this method? Whit token you used?

Should I have to mention below method which is given in firebase_messaging documentation?

No, you don't need this method, it is just an example, how to send push notification from the app. Our server does similar logic when you create an event or send a push notification from the ConnectyCube admin panel. But you can use it for testing push notifications on your device without the Connectycube server.

@TatankaConCube

how you created subscriptions before without this method?

I use in all above method in this way. If I made mistake then suggest me.
void onSendChatMessage(String content) async {
    await notificationEnable();
    if (content.trim() != '') {
      final message = createCubeMsg();
      message.body = content.trim();
      await subScription();
      await init();

      sendPushNotification();
      onSendMessage(message);
    } else {
      Fluttertoast.showToast(msg: 'Nothing to send');
    }
  }

Whit token you used?
Now, I get token with in init() method.

In init() method I use token

if (connector.token.value != null) {
      String token = connector.token.value;
      print('Exist token: $token');
    } else {
      connector.token.addListener(() {
        String token = connector.token.value;
        print('Updated token: $token');
      });

In subscription() method, I use this token

parameters.pushToken = '${_cubeDialog.getRecipientId()}...${_cubeDialog.userId}';

Try to clear all app data, then completely remove it from the device and install it again. During writing documentation, I did the same step by step and it worked. I can't understand why it does not work for you (((

parameters.pushToken it is 'key', which FCM uses for identifying your device. It is like 'receiverId' for FCM when the Connectycube server sends push notifications. It should be the only token from the system, but not any random data.

parameters.pushToken it is 'key', which FCM uses for identifying your device. It is like 'receiverId' for FCM when the Connectycube server sends push notifications. It should be the only token from the system, but not any random data.
@TatankaConCube
But sir I did not know hoe to get this 'key', I mean 'receiverId'. Actually, I mean where I can get this?

In our example it is the method getToken(). You can try to use another plugins for getting this data.

In our example it is the method getToken(). You can try to use another plugins for getting this data.

@TatankaConCube
I check full code but I can't find getToken()  method. Please suggest me which plugin I should use for getting this data.

I mean this part from our doc
// getting token which used for subscription on Push Notifications on ConnectyCube server
  if (connector.token.value != null) {
    String token = connector.token.value;
    log('Exist token: $token');
  } else {
    connector.token.addListener(() {
      String token = connector.token.value;
      log('Updated token: $token');
    });
  }

@TatankaConCube
I tried everything but I didn't get any solution. If you have demo file of notification code snippet then please share.

@Significantinfotech2020 during writing the documentation I used this draft branch for testing. There part of code related to creation subscription. You can try to add something similar to your project.

@Significantinfotech2020 during writing the documentation I used this draft branch for testing. There part of code related to creation subscription. You can try to add something similar to your project.

@TatankaConCube
I tried as you suggest, but now I got this error log from dashboard notification.
{
  "notification": {
    "id": 6901158,
    "badge": null,
    "device_token": null,
    "sound": "default",
    "alert": null,
    "data": {
      "message": "dt7vh",
      "custom_parameter1": "FLUTTER_NOTIFICATION_CLICK",
      "custom_parameter2": "custom parameter value 2",
      "collapse_key": "event3372039"
    },
    "expiry": 86400,
    "delivered": false,
    "delivered_at": null,
    "failed": true,
    "failed_at": "2020-10-26T10:33:52+00:00",
    "fail_after": "2020-10-26T11:33:42+00:00",
    "retries": 0,
    "error_code": null,
    "error_description": "Unable to deliver notification 6901158, received error (Failed to deliver to recipients 0, 1. Errors: InvalidRegistration, InvalidRegistration.)",
    "deliver_after": null,
    "alert_is_json": null,
    "app_id": 1283,
    "collapse_key": null,
    "delay_while_idle": false,
    "registration_ids": [
      "ad156f91103bd48a",
      "e1f422d058f5ec16",
      "d4doPAAuTUm2c6jfr-I-PM:APA91bFgD55qnOoYAk74GV5aIR6dHIMKaY4Pbz-319cY7aTjVKDcrycw7agET9I4cOwxQcfMs7uYJ38i2QAzXEjDPdOmyYbqL62kJ06OnIyq9fCcvvGuKJ9WiJMnezdX8JlXEQXkHHcP",
      "ezAU2ZFgRZuuicqM9C7bTi:APA91bGPXBBtbdi5_MFSfMkOZQ80FaBlfUa-mOrh3R4jFL0XkQDcM3YAF8kqdH31XnKG75XEuZ4mFV2NR-e162QPm6mwt_3JguRohA8fARk_VOXo4rOA40MKqkEEsVbzGhLbxAZpOvzT"
    ],
    "uri": null,
    "priority": 10,
    "url_args": null,
    "category": null,
    "content_available": false,
    "mutable_content": false,
    "notification": null,
    "type": "Rpush::Client::Redis::Gcm::Notification",
    "event_id": 3372039,
    "event_date": "2020-10-26T10:33:42+00:00"
  },
  "log": [
    {
      "device_token": null,
      "delivered_at": null,
      "failed_at": "2020-10-26T10:33:52+00:00",
      "error_code": null,
      "error_description": "Unable to deliver notification 6901158, received error (Failed to deliver to recipients 0, 1. Errors: InvalidRegistration, InvalidRegistration.)"
    }
  ]
}

Now, If you catch exact problem, then help me asap.

Can you get a token from FCM on the device now? Can you provide logs with the subscription creation process? Looks like you have the same error as before.

@TatankaConCube

Can you get a token from FCM on the device now?

Yes, but in firebase console when I clicked on cloud messaging tab, It has no any send notification.

Can you provide logs with the subscription creation process?

I/flutter (31956): CB-SDK: : =========================================================
I/flutter (31956): === REQUEST ==== baa7ccb0-2ad5-49b0-ae9c-2f599e13cecc ===
I/flutter (31956): REQUEST
I/flutter (31956):   POST https://api.connectycube.com/subscriptions
I/flutter (31956): HEADERS
I/flutter (31956):   {Content-type: application/json, ConnectyCube-REST-API-Version: 0.1.1, CB-SDK: Flutter 0.5.0, CB-Token: eb0d292af15156876556be15d5d162eeac000dd4}
I/flutter (31956): BODY
I/flutter (31956):   {"notification_channel":"gcm","device":{"udid":"ad156f91103bd48a","platform":"android"},"push_token":{"environment":"development","client_identificatio
n_sequence":"d4doPAAuTUm2c6jfr-I-PM:APA91bFgD55qnOoYAk74GV5aIR6dHIMKaY4Pbz-319cY7aTjVKDcrycw7agET9I4cOwxQcfMs7uYJ38i2QAzXEjDPdOmyYbqL62kJ06OnIyq9fCcvvGuKJ9WiJMnezdX8JlXEQXk
HHcP","bundle_identifier":"com.example.chatconnectycubesdk"}}

This log I got when subscription method called.
SUBSCRIPTION SUCCESS ====> [{notification_channel: gcm, push_token: null, device: {udid: ad156f91103bd48a, platform: android}}]
Code run as success but push_token get null.

Also one parameter got null from sendNotification() method and its log is

CUBE EVENT -----> [{notification_type: null, environment: development, message: {message: cfrthhu, custom_parameter1: FLUTTER_NOTIFICATION_CLICK, custom_
parameter2: custom parameter value 2}, event_type: one_shot}]

Looks like you have the same error as before.

Yes, but in dashboard when I clicked on Push Notification -> Queue tab, notification status, it displays 2 Delivered, 2 Failed and above log.

Try to remove all subscriptions in the Connectycube dashboard and do the same again  (reinstall the app (delete completely and install it again), subscribe, and send push notification). And see logs from in callbacks for receiving push notifications on your device, I mean them:
connector.configure(
    onLaunch: onLaunch,
    onMessage: onMessage,
    onResume: onResume,
    onBackgroundMessage: onBackgroundMessage);

Try to remove all subscriptions in the Connectycube dashboard and do the same again (reinstall the app (delete completely and install it again), subscribe, and send push notification). And see logs from in callbacks for receiving push notifications on your device, I mean them:
connector.configure(
    onLaunch: onLaunch,
    onMessage: onMessage,
    onResume: onResume,
    onBackgroundMessage: onBackgroundMessage);

@TatankaConCube
I did same step as you suggest, now I get title and body parameter null in onMessage() method.
This is notification log from dashboard. but still I didn't get notification and any changes in firebase console cloud messaging.
{
  "notification": {
    "id": 6905941,
    "badge": null,
    "device_token": null,
    "sound": "default",
    "alert": null,
    "data": {
      "message": "hii",
      "custom_parameter1": "FLUTTER_NOTIFICATION_CLICK",
      "custom_parameter2": "custom parameter value 2",
      "collapse_key": "event3374654"
    },
    "expiry": 86400,
    "delivered": true,
    "delivered_at": "2020-10-26T11:31:03+00:00",
    "failed": null,
    "failed_at": null,
    "fail_after": "2020-10-26T12:31:03+00:00",
    "retries": 0,
    "error_code": null,
    "error_description": null,
    "deliver_after": null,
    "alert_is_json": null,
    "app_id": 1283,
    "collapse_key": null,
    "delay_while_idle": false,
    "registration_ids": [
      "exid1TofSUis39TSygwM3v:APA91bF5r8sYKWcGfMPDrL5UoqYPcQ0A8e_yz_ZEIIV6OubKb8PWG_b1z_kX1sbn96lwNYOQ5-1COx6xKcBofCIexhUOJvpihP4zUnRKCfsfuWv9Bx9htEreHHTIZreNRCcW6ab6QEg0",
      "dSaTJ6IFS22N1EcVXO68NA:APA91bFLgSQEc2ezPtRSfBSEc3M_PUnkzrJYuh2dMo3PY-wRBWNaLVYEkYABCXnBHWHmI6qOehEWGkbbT8BBW_9BmsITQBlB_dlX_397r7xmPc8U0T3avxZhCN8HyQ770EstdtwR41Lt"
    ],
    "uri": null,
    "priority": 10,
    "url_args": null,
    "category": null,
    "content_available": false,
    "mutable_content": false,
    "notification": null,
    "type": "Rpush::Client::Redis::Gcm::Notification",
    "event_id": 3374654,
    "event_date": "2020-10-26T11:31:02+00:00"
  },
  "log": [
    {
      "device_token": null,
      "delivered_at": "2020-10-26T11:31:03+00:00",
      "failed_at": null,
      "error_code": null,
      "error_description": null
    }
  ]
}

I did same step as you suggest, now I get title and body parameter null in onMessage() method.

does it mean you receive a push notification on the device?
FYI, ConnectyCube server sends push notification with type 'data' not 'notification' it means you have search your data in parameter 'data', like in my draft code

does it mean you receive a push notification on the device?

@TatankaConCube
No, I don't receive notification on device but only got above log. Also there is nothing changes in firebase console.

what means it?

now I get title and body parameter null in onMessage() method

In the log I can't see any errors, it means the Connectycube server successfully sent a push notification to FCM server. Please add logs to all callbacks and try to send push notification again.

"delivered": true,
"delivered_at": "2020-10-26T11:31:03+00:00",

it means push notification successfully delivered to FCM server

Dear @TatankaConCube
For Firebase connection with connectycube_sdk, I have confusions are that

Should I have to on any authentication filed like email/password or phone in firebase console?

While using firebase_messaging packages to configure project, I have to define this two steps in my project or not?

5. Define a TOP-LEVEL or STATIC function to handle background messages
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

Note: the protocol of data and notification are in line with the fields defined by a RemoteMessage.
6. Set onBackgroundMessage handler when calling configure
_firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        _showItemDialog(message);
      },
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        _navigateToItemDetail(message);
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        _navigateToItemDetail(message);
      },
    );

Note: configure should be called early in the lifecycle of your application so that it can be ready to receive messages as early as possible. See the example app for a demonstration.
Because this two method is same with connectycube_sdk methods. That's why I have this confusion?

Dear @TatankaConCube
For Firebase connection with connectycube_sdk, I have confusions are that

Should I have to enable any authentication sign-in option  filed like email/password or phone in firebase console?
While using firebase_messaging packages to configure project, I have to define this two steps in my project or not?

5. Define a TOP-LEVEL or STATIC function to handle background messages
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

Note: the protocol of data and notification are in line with the fields defined by a RemoteMessage.
6. Set onBackgroundMessage handler when calling configure
_firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        _showItemDialog(message);
      },
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        _navigateToItemDetail(message);
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        _navigateToItemDetail(message);
      },
    );

Note: configure should be called early in the lifecycle of your application so that it can be ready to receive messages as early as possible. See the example app for a demonstration.
Because this two method is same as connectycube_sdk methods. That's why I have this confusion?

@TatankaConCube
Please give me answer asap for my confusion.

From the Firebase console you need:

enable Cloud messaging;
get Server token for Connectycube admin panel;
download and add to project google-services.json;
These three points required from Firebase for working with FCM;

I have to define this two steps in my project or not?

yes, you have to create this static method and set it as the listener for the onBackgroundMessage callback.

@TatankaConCube

you have to create this static method and set it as the listener for the onBackgroundMessage callback.

Please help me how and where I have to change in code snippet. I mean in init() method I have to initialize any function?

you can initialize plugin in method void initState() of your widget where you have logged in user. In this place, you can set listeners for events. The main thing - you have to do this immediately when you got logged in user.

@TatankaConCube
How can I get title and body parameter in onMessage() method while sending push_notification which I get null.
onMessage: {notification: {title: null, body: null}, data: {custom_parameter1: FLUTTER_NOTIFICATION_CLICK, custom_parameter2: custom parameter value 2, message: greyj}}

@TatankaConCube
How can I get title and body parameter in onMessage() method while sending push_notification which I get null.
onMessage: {notification: {title: null, body: null}, data: {custom_parameter1: FLUTTER_NOTIFICATION_CLICK, custom_parameter2: custom parameter value 2, message: greyj}}
Please give me suggestion asap.

@TatankaConCube
Please give solution of above question. Please reply!!

As I said before, the Connectycube server sends push notifications with type 'data', so you can add all required information to  'parameters' during the event creation. You can add all the needed data to this parameter.
One question - did I right understand, now you can receive push notifications on the device?

As I said before, the Connectycube server sends push notifications with type 'data', so you can add all required information to 'parameters' during the event creation. You can add all the needed data to this parameter.

@TatankaConCube

This data I use for creating event. In this I mention all of the data which required as per documentation. Please check below code and if made mistake then please suggest me.

void sendPushNotification() {
    CreateEventParams params = CreateEventParams();
    params.parameters = {
      'message': '${textEditingController.text}',
      'custom_parameter1': 'custom parameter value 1',
      'custom_parameter2': "custom parameter value 2",
      'ios_voip': 1
    };
    params.notificationType = '${NotificationType.PUSH}';
    params.environment = CubeEnvironment.DEVELOPMENT;
    params.usersIds = _cubeDialog.occupantsIds;

    createEvent(params.getEventForRequest()).then((cubeEvent) {
      print('CUBE EVENT -----> $cubeEvent');
    }).catchError((error) {
      print('CUBE EVENT ERROR -----> $error');
    });
  }

One question - did I right understand, now you can receive push notifications on the device?

I can receive notification, if I get onMessage() method in 'data' parameter rather than 'notification'. Sorry, still I did not receive notification on device. But It successfully generated from connectycube dashboard.
onMessage: {notification: {title: null, body: null}, data: {custom_parameter1: FLUTTER_NOTIFICATION_CLICK, custom_parameter2: custom parameter value 2, message: greyj}}

As I said before, the Connectycube server sends push notifications with type 'data', so you can add all required information to 'parameters' during the event creation. You can add all the needed data to this parameter.

@TatankaConCube
In above code snippet where I have pass 'data' as you said? Please suggest me.

it can be like:
params.parameters = {
      'message': '${textEditingController.text}',
      'title': someTitle,
      'body': someBody,
// all needed parameters here
      'ios_voip': 1
    };

it can be like:
params.parameters = {
      'message': '${textEditingController.text}',
      'title': someTitle,
      'body': someBody,
// all needed parameters here
      'ios_voip': 1
    };

@TatankaConCube
I did exact same as you suggest but still I face that title and parameter null in onMessage() method. What should I do now?
params.parameters = {
'message': '${textEditingController.text}',
'title': 'Chat Notification',
'body': "chat body",
'notification_type': 'push',
'push_type': 'gcm',
'environment': 'development',
'ios_voip': 1,
'usersIds' = ${_cubeDialog.occupantsIds}
};

in the 'data' field? are you sure?
please provide log, like you did before. I mean it:

onMessage: {notification: {title: null, body: null}, data: {custom_parameter1: FLUTTER_NOTIFICATION_CLICK, custom_parameter2: custom parameter value 2, message: greyj}}

@TatankaConCube

in the 'data' field? are you sure?

Yes.

please provide log, like you did before. I mean it:

onMessage, message: {notification: {title: null, body: null}, data: {notification_type: push, push_type: gcm, environment: development, body: c
hat body, title: Chat Notification, message: gfghgg}}

what about it:

data: {notification_type: push, push_type: gcm, environment: development, body: chat body, title: Chat Notification, message: gfghgg}

why you say

title and parameter null in onMessage()

I'm confused...

what about it:

data: {notification_type: push, push_type: gcm, environment: development, body: chat body, title: Chat Notification, message: gfghgg}

why you say

title and parameter null in onMessage()

I'm confused...

sorry for this.
but still I didn't receive notification.

do you mean notification in the Android notifications center? For the Android platform, you should do it by yourself, please read our documentation (at the end of the section). For iOS, it is a system feature and here you can manage only actions, which happen by clicking on the notification.

@shivanijha002

Notification: title and body should not be null. How can I set these values?

For the Android platform, you have to set them to the parameters map, for iOS you can use some additional parameter from our API. Note: ConnectyCube server always sends GCM with 'data' type, not 'notification'.

Also, I do not get any notification on device. Though message is getting captured in debug console.

For Android, it is expected behavior. You have to do it yourself. For example, you can use flutter_local_notifications plugin for it.
For iOS, it is a system feature and the system does it instead of you.

Thank you for the details. It might be useful if you can add it in your documentation. I wasted 2 days trying out different things and hoping it will work without anything external.
flutter_local_notifications has worked for me on Android.

Hello @shivanijha002
I face same issue as you mentioned above. Please suggest me how can I use flutter_local_notifications with firebase_messaging for Android device notification. Please suggest me asap.

@Significantinfotech2020 in your callback onMessage  you have all the needed data, please read documentation how to configure notification with this data and how to show it.

Hello @TatankaConCube,
I share my chat_dialog_screen.dart  file. In this file I implemented flutter_local_notifications with firebase_messaging, but still I can't get any notification on receiver device.
So, please check my code and let me know where I made mistake? What changes I have to do in this code?

There are few plugins for listening push notifications and a lot of code is commented. Do you receive a push event in your callbacks?
I'm going to plan to add a push notification feature for the Chat sample in the next iteration.

@Significantinfotech2020  today I pushed draft code for enabling push notifications in the Chat sample. The main logic for subscription, listening push notifications and showing local notifications placed in push_notifications_manager.dart
At current moment works (tested on iOS and Android):

subscription on push notifications;
receiving push notifications in the background (or killed) and foreground;
displaying notifications in Notification Center;
unsubscription from push notifications after logout from the app;

Note: it is just a draft and not all features implemented yet, for example, navigation to concrete chat by notification click, etc.

@Significantinfotech2020 today I pushed draft code for enabling push notifications in the Chat sample. The main logic for subscription, listening push notifications and showing local notifications placed in push_notifications_manager.dart
At current moment works (tested on iOS and Android):

subscription on push notifications;
receiving push notifications in the background (or killed) and foreground;
displaying notifications in Notification Center;
unsubscription from push notifications after logout from the app;

Note: it is just a draft and not all features implemented yet, for example, navigation to concrete chat by notification click, etc.

@TatankaConCube I checked this code. It's working as you describe. Thanks 👍

Hello @TatankaConCube
In your code sometimes I got notification but sometimes not. I had updated code as per latest documentation. There was not any error in the terminal.

In which way do you send push notification? From admin panel?

@TatankaConCube

In which way do you send push notification?

I am sending notification as per your updated code.

From admin panel?

No.

Did these notifications present in the queue in the Admin panel?

Did these notifications present in the queue in the Admin panel?

when I receive notification on device that entries were in admin panel, but when I not get notification, that entry was not in queue.

it means you have a problem not with receiving but with sending notifications, investigate this part of your code

@TatankaConCube In below method 6543 is what? Is this application ID or Account ID or anything else?
FlutterLocalNotificationsPlugin().show(
    6543,
    "Chat sample",
    data['message'].toString(),
    platformChannelSpecifics,
    payload: 'item x',
  );

There is code not from our SDK, it is a code of flutter_local_notifications plugin. There is the description for this code example. In my example, 6543 is just a random notification id. Notification id - for the Android system it is the unique id of your notification, by this id you can cancel notification, update it, etc.

Implemented in the latest version. Closing...


Policy generation can take a long time for a large number of unique labels

Currently, if you import a very large CIDR policy when there are several pods being managed by Cilium, then endpoint regeneration may be triggered several times, and each endpoint regeneration takes a long time to calculate policy, and they fight for attention from the CPU. If it takes too long, then the 10s timeout below will expire and policy won't be applied to the proxy within this time (because not enough CPU is available to calculate the allowedIdentities, push through XDS, have Envoy ack all within the timeframe). This leads to failure to apply policy. In k8s mode where the policy application is triggered from events from k8s, this will retry and Cilium will get stuck in a state where it constantly attempts to apply the policies, regenerate endpoints, fail to apply policy to the proxy, fail out, and retry again.
https://github.com/cilium/cilium/blob/5d39d0e41b193a9e891495709b151839056026b1/pkg/endpoint/bpf.go#L674-L681
https://github.com/cilium/cilium/blob/5d39d0e41b193a9e891495709b151839056026b1/pkg/endpoint/bpf.go#L781-L785
~If we limit the number of concurrent pod regenerations to the number of available CPUs, then this may mitigate issues like the above because enough CPU should be available to push through even a fairly large policy.~
Apparently we already do this, see the first comments below.
Other avenues for investigation:

Make policy computation more efficient (@ianvernon has some WIP on this)
Figure out the limitations on number of rules we can configure and consider gating policies based on this, before they cause Cilium to get into a bad state

Related: https://github.com/cilium/cilium/issues/4396

@joestringer perhaps setting up ncpu := runtime.NumCPU() - 1 would help?
https://github.com/cilium/cilium/blob/812eee2c8035747ee3292600ade6fb5a3cf40285/daemon/daemon.go#L1574-L1583

@aanm I wonder if even that is reasonable. What if a CPU-heavy workload is running while we attempt to install policy? Cilium assumes it can burst to the entire CPU?

Upon further investigation, I'm noticing these callstacks:
goroutine 26448088 [semacquire]:
sync.runtime_SemacquireMutex(0xc42012e084, 0xffffff00)
        /usr/local/go/src/runtime/sema.go:71 +0x3d
sync.(*Mutex).Lock(0xc42012e080)
        /usr/local/go/src/sync/mutex.go:134 +0xee
regexp.(*Regexp).get(0xc42012e000, 0x0)
        /usr/local/go/src/regexp/regexp.go:211 +0x3d
regexp.(*Regexp).doExecute(0xc42012e000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc42c2d9875, 0x2, 0x0, 0x0, ...)
        /usr/local/go/src/regexp/exec.go:420 +0x40
regexp.(*Regexp).doMatch(0xc42012e000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc42c2d9875, 0x2, 0x2)
        /usr/local/go/src/regexp/exec.go:412 +0xc8
regexp.(*Regexp).MatchString(0xc42012e000, 0xc42c2d9875, 0x2, 0x0)
        /usr/local/go/src/regexp/regexp.go:435 +0x6c
github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/util/validation.IsQualifiedName(0xc42c2d9860, 0x17, 0xf, 0x1b, 0xc421ea3370)
        /go/src/github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go:66 +0xe4
github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/labels.validateLabelKey(0xc42c2d9860, 0x17, 0x7f5a16f466c8, 0x0)
        /go/src/github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/labels/selector.go:822 +0x42
github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/labels.NewRequirement(0xc42c2d9860, 0x17, 0x2b6b351, 0x1, 0xc428657110, 0x1, 0x1, 0x22, 0x40, 0xc42c2d9860)
        /go/src/github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/labels/selector.go:135 +0x3f
github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelectorAsSelector(0xc42337a9a0, 0x18, 0x29eb940, 0x0, 0x60000000000)
        /go/src/github.com/cilium/cilium/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go:40 +0x1f5
github.com/cilium/cilium/pkg/policy/api.(*EndpointSelector).Matches(0xc4219182d8, 0x3be7260, 0xc42cdd5b80, 0xc42cdd5b80)
        /go/src/github.com/cilium/cilium/pkg/policy/api/selector.go:209 +0x43
github.com/cilium/cilium/pkg/endpoint.getSecurityIdentities(0xc4294047e0, 0xc4219182d8, 0xc4305f4e50, 0x1, 0x2)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:75 +0x184
github.com/cilium/cilium/pkg/endpoint.(*Endpoint).convertL4FilterToPolicyMapKeys(0xc4200cdb80, 0xc421ea3a10, 0x10610620000b501, 0xc42e4e3a78, 0x7d4, 0x900)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:96 +0x1ea
github.com/cilium/cilium/pkg/endpoint.(*Endpoint).computeDesiredL4PolicyMapEntries(0xc4200cdb80, 0xc4257cfc50)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:128 +0x325
github.com/cilium/cilium/pkg/endpoint.(*Endpoint).computeDesiredPolicyMapState(0xc4200cdb80, 0x3c0d080, 0xc421bdb200, 0xc421f4c018, 0xc4204a5c00)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:207 +0x96
github.com/cilium/cilium/pkg/endpoint.(*Endpoint).regeneratePolicy(0xc4200cdb80, 0x3c0d080, 0xc421bdb200, 0xc421ea3d48, 0x0, 0x0, 0x0)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:557 +0x507
github.com/cilium/cilium/pkg/endpoint.(*Endpoint).TriggerPolicyUpdatesLocked(0xc4200cdb80, 0x3c0d080, 0xc421bdb200, 0x0, 0x150f609, 0xc4256a43c0, 0x3bd9201)
        /go/src/github.com/cilium/cilium/pkg/endpoint/policy.go:785 +0x77
github.com/cilium/cilium/pkg/endpointmanager.TriggerPolicyUpdates.func1(0x3c0d080, 0xc421bdb200, 0xc42d6d5701, 0xc4200cdb80, 0xc429a0ea40)
        /go/src/github.com/cilium/cilium/pkg/endpointmanager/manager.go:266 +0x6e
created by github.com/cilium/cilium/pkg/endpointmanager.TriggerPolicyUpdates
        /go/src/github.com/cilium/cilium/pkg/endpointmanager/manager.go:264 +0xbf

Seems like we're constructing brand new labelselectors every time we attempt to match a label in policy, and this is doing various bits of validation, including grabbing global regex mutexes. This basically serializes each of the threads.

Removed the 1.2-bugfix as the first part of this issue was already fixed by @ianvernon

The spirit of this issue should be addressed in https://github.com/cilium/cilium/projects/23 ; Closing.


Adjust folder structure

This is to mirror directory structure of refactor which will be tested and merged soon

First step in getting changes from #171 merged


private torrent not download

my code: http://codepen.io/anon/pen/GoPLVM/?editors=0010
torrent file encode: http://codepen.io/anon/pen/wMRbvj?editors=0010
debug log: http://codepen.io/anon/pen/GoPagO?editors=0010

Since what you're trying to do is illegal, your issue will most likely be closed, as is the policy of this project. Webtorrent requires other webtorrent-compatible peers to be in the swarm, discoverable via a webtorrent-compatible tracker.

Please do not use WebTorrent for copyright infringement. We cannot help you.


Building vApp fails

I'm not able to provision to vcloud air.
In stage "Building vApp..." I'm receiving following error:
.vagrant.d/gems/gems/vagrant-vcloudair-0.5.2/lib/vagrant-vcloudair/action/build_vapp.rb:117:in `call': undefined method `last' for nil:NilClass (NoMethodError)
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builder.rb:116:in `call'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `block in run'
...

Vagrant 1.7.2
vagrant-vcloudair (0.5.2)
Windows 7

Can you provide your Vagrantfile configuration ? (clean the password, and confidential fields if any)
Then launch the following command:
VAGRANT_LOG=debug vagrant up

sure:
Vagrant.configure(2) do |config|

  config.vm.box = "vchrisb/openSUSE-13.2_64"

  # Set up hostname
  config.vm.hostname = "test.lab.local"

  # vCloud Air provider settings
  config.vm.provider :vcloudair do |vcloudair|

    vcloudair.username = ''
    vcloudair.password = ''

    # if you're using a vCloud Air Dedicated Cloud, put the cloud id here, if
    # you're using a Virtual Private Cloud, skip this parameter.
    vcloudair.vdc_name = ''

    # Set the network to deploy our VM on (case sensitive)
    vcloudair.vdc_network_name = ''

    # Set our Edge Gateway and the public IP we're going to use.
    vcloudair.vdc_edge_gateway = ''
    vcloudair.vdc_edge_gateway_ip = ''

    # Catalog that holds our templates.
    vcloudair.catalog_name = 'Vagrant'

    # Set our Memory and CPU to a sensible value for Docker.
    vcloudair.memory = 1024
    vcloudair.cpus = 2
  end

end
2

The debug log is quite lengthy and does include a lot of sensitive date. Here is the output of the last lines:
 INFO inventory_check: Catalog [Vagrant] exists
 INFO inventory_check: Using catalog item [vchrisb/openSUSE-13.2_64] in Catalog [Vagrant]...
 INFO interface: info: Testing Network Configuration in vCloud Air...
 INFO interface: info: ==> default: Testing Network Configuration in vCloud Air...
DEBUG driver_5_1: Our IP range: 391968161..391968161
DEBUG driver_5_1: Our Test IP 391962948
DEBUG driver_5_1: Our IP range: 391962948..391962948
DEBUG driver_5_1: Our Test IP 391962948
DEBUG driver_5_1: Found IP <IP_ADDRESS>
DEBUG driver_5_1: Our IP range: 391962944..391962944
DEBUG driver_5_1: Our Test IP 391962948
INFO warden: Calling IN action: #<Vagrant::Action::Builtin::Call:0x40f6308>
 INFO runner: Preparing hooks for middleware sequence...
 INFO runner: 1 hooks defined.
 INFO runner: Running action: #<Vagrant::Action::Builder:0x3bb2948>
 INFO warden: Calling IN action: #<VagrantPlugins::VCloudAir::Action::IsCreated:0x3bbbfa8>
 WARN is_created: vApp has not been created
 INFO warden: Calling OUT action: #<VagrantPlugins::VCloudAir::Action::IsCreated:0x3bbbfa8>
 INFO runner: Preparing hooks for middleware sequence...
 INFO runner: 1 hooks defined.
 INFO runner: Running action: #<Vagrant::Action::Warden:0x2c83a10>
 INFO warden: Calling IN action: #<Proc:0x37ef138@C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:94 (lambda)>
 INFO warden: Calling IN action: #<VagrantPlugins::VCloudAir::Action::BuildVApp:0x2c83968>
DEBUG build_vapp: DNS1: <IP_ADDRESS> DNS2: <IP_ADDRESS>
 INFO interface: info: Building vApp...
 INFO interface: info: ==> default: Building vApp...
ERROR warden: Error occurred: undefined method `last' for nil:NilClass
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
ERROR warden: Error occurred: undefined method `last' for nil:NilClass
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
ERROR warden: Error occurred: undefined method `last' for nil:NilClass
 INFO warden: Beginning recovery process...
 INFO warden: Calling recover: #<Vagrant::Action::Builtin::Call:0x40f6308>
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Calling recover: #<Vagrant::Action::Builtin::Call:0x408a1e8>
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Recovery complete.
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
ERROR warden: Error occurred: undefined method `last' for nil:NilClass
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
ERROR warden: Error occurred: undefined method `last' for nil:NilClass
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO warden: Beginning recovery process...
 INFO warden: Recovery complete.
 INFO environment: Released process lock: machine-action-df6fca0dd86845707f9ef793863f9bd8
 INFO environment: Running hook: environment_unload
 INFO runner: Preparing hooks for middleware sequence...
 INFO runner: 1 hooks defined.
 INFO runner: Running action: #<Vagrant::Action::Builder:0x38bfbc0>
C:/Users/USER/.vagrant.d/gems/gems/vagrant-vcloudair-0.5.2/lib/vagrant-vcloudair/action/build_vapp.rb:117:in `call': undefined method `last' for nil:NilClass (NoMethodError)
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builder.rb:116:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `block in run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/util/busy.rb:19:in `busy'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builtin/call.rb:53:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/Users/USER/.vagrant.d/gems/gems/vagrant-vcloudair-0.5.2/lib/vagrant-vcloudair/action/inventory_check.rb:15:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/Users/USER/.vagrant.d/gems/gems/vagrant-vcloudair-0.5.2/lib/vagrant-vcloudair/action/connect_vcloud.rb:49:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builtin/handle_box.rb:56:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builder.rb:116:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `block in run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/util/busy.rb:19:in `busy'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builtin/call.rb:53:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builtin/config_validate.rb:25:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/warden.rb:34:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/builder.rb:116:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `block in run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/util/busy.rb:19:in `busy'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/action/runner.rb:66:in `run'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/machine.rb:214:in `action_raw'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/machine.rb:191:in `block in action'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/environment.rb:516:in `lock'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/machine.rb:178:in `call'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/machine.rb:178:in `action'
	from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/batch_action.rb:82:in `block (2 levels) in run'

Thank You!

I am getting the same error when I try to provision to vCloud Air. It happens after creating the vApp Template and also when the template already exists:
vagrant (1.7.4)
vagrant-vcloudair (0.5.2)
Fedora 22
Bringing machine 'vchs-oc01' up with 'vcloudair' provider...
==> vchs-oc01: Adding VM to existing vApp...
/home/builduser/.vagrant.d/gems/gems/vagrant-vcloudair-0.5.2/lib/vagrant-vcloudair/action/build_vapp.rb:182:in `call': undefined method `last' for nil:NilClass (NoMethodError)
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/warden.rb:34:in `call'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/warden.rb:34:in `call'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/warden.rb:34:in `call'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/builder.rb:116:in `call'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/runner.rb:66:in `block in run'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/util/busy.rb:19:in `busy'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/runner.rb:66:in `run'
        from /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/lib/vagrant/action/builtin/call.rb:53:in `call'
...

Here is my existing Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'vcloudair'

nodes = [
  { hostname: 'vchs-oc01', box: 'centos7-x64-vmware_ovf-1' },
]

Vagrant.configure('2') do |config|

  # vCloud Air provider settings
  config.vm.provider :vcloudair do |vcloudair|

    vcloudair.username = '********'
    vcloudair.password = '********'

    vcloudair.vdc_name = '********'

    vcloudair.network_bridge = true
    vcloudair.vdc_network_name = 'VCHS Server Net'
    vcloudair.catalog_name = 'Vagrant'

    vcloudair.memory = 2048
    vcloudair.cpus = 2
  end

  nodes.each do |node|
    config.vm.define node[:hostname] do |node_config|
      node_config.vm.box = node[:box]
      node_config.vm.hostname = node[:hostname]
    end
  end

end


The build options passed to the start build endpoint should be arbitrary JSON

Currently, the build options in TranslationBuildConfigDto is a string. This should hold arbitrary JSON and not a string.

I'm assuming it should be a JsonObject then.

Yeah, this shouldn't be a problem. We discussed it earlier, but it wasn't a top priority. I can go ahead and take care of this.

It might be tricky getting this to work with NSwag.

Yeah, that's the difficult part - that's why it wasn't done initially. I'm investigating though.


Add a Servlet that passed all the information to the frontend.

New Classes:
Investment.java --> contains information needed when user makes a purchase
SearchItem.java --> represent a search query and it's popularity
User.java --> global object use in all competition
UserCompetitionInfo.java --> user information about one specific competition
All information is passes through the AllInfomationServlet.java the data is hard coded for now.
I tried my best with naming everything but please let me know if some of the name doesn't make sense or there's a better word for it.

yup I'm having a look into it.

yup I'm having a look into it.


disable file creation in root dir

Whenever i run my main.py file where i use instabot, it creates lots of different files in the directory. How can i disable this?

setting bot.base_path does not work. I have tried next variants, none worked:
bot.base_path = "libfiles"
bot.base_path = "libfiles/"
bot.base_path = "/libfiles"
bot.base_path = "/libfiles/"
bot.base_path = "./libfiles/"

also setting next params does not stop the bot from creating the files
bot.blacklist_file = ""
bot.whitelist_file = ""
bot.comments_file = ""
bot.unfollowed_file = ""
bot.skipped_file = ""
bot.followed_file = ""

also setting files like this does not help:
base_dir = "libfiles/"
bot.base_path = base_dir
bot.blacklist_file = base_dir + "blacklist.txt"
bot.whitelist_file = base_dir + "whitelist.txt"
bot.comments_file = base_dir + "comments.txt"
bot.unfollowed_file = base_dir + "unfollowed.txt"
bot.skipped_file = base_dir + "skipped.txt"
bot.followed_file = base_dir + "followed.txt"

There must be some kind of a bug

... or some kind of shitcode. We need a contributor to implement a more elegant way to solve this.

I have the same problem. I managed to create the other files in a different folder but the config & log folder & 2 other files are still getting created on the root folder.
bot = Bot(
            whitelist_file=util_path + '/whitelist.txt',
            blacklist_file=util_path + '/blacklist.txt',
            comments_file=util_path + '/comments.txt',
            followed_file=util_path + '/followed.txt',
            unfollowed_file=util_path + '/unfollowed.txt',
            skipped_file=util_path + '/skipped.txt',
            friends_file=util_path + '/friends.txt',
)

Whenever i try to use the parameter base_path here i am getting "No such file or directory" error.


Column mapping removal: support CDC enabled tables

Which Delta project/connector is this regarding?

[x] Spark
[ ] Standalone
[ ] Flink
[ ] Kernel
[ ] Other (fill in here)

Description

Extend CDC support around column mapping removal.
Most notably, ensure CDC data is not generated for the column mapping removal commit and prohibit reading CDC data across column mapping removal boundary.
How was this patch tested?
New unit tests

Does this PR introduce any user-facing changes?

@tomvanbussel could you have a look at this one please?