Retrieving user metadata about a provisioned SoftLayer server comes back null - ruby

I'm trying to retrieve the user meta information for each machine consistently but what I'm finding is most of my machines are missing this data. I'd like to understand better what is required for this user data to be there. I'm curious if a server can be requested and provisioned without requiring user information (e.g. an API call to order a server and no user data is given). Or whether I am missing something in how I retrieve this information. Here is the basic ruby program I'm running:
user = ###
api_key = ###
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
list_of_virtual_machines = client['Account'].result_limit(i*50,50).object_mask("mask[id, billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], userData]").getVirtualGuests
for x in 0..list_of_virtual_machines.length - 1
pp list_of_virtual_machines[i]['userData']
if list_of_virtual_machines[i]['billingItem'] && list_of_virtual_machines[i]['billingItem']['orderItem'] && list_of_virtual_machines[i]['billingItem']['orderItem']['order'] && list_of_virtual_machines[i]['billingItem']['orderItem']['order']['userRecord']
pp list_of_virtual_machines[i]['billingItem']['orderItem']['order']['userRecord']
end
end
My prints are consistently showing null. This question is related to a similar question I asked not too long ago (but the focus of that question moved towards the provisionDate):
How to get order username and provisionDate for all SoftLayer machines using Ruby?

They are missing that data because you did not added.
you can create the user data at moment to order a new server or VSI, you just have to send the data in your order request either using the createObject method or the placeOrder method. see http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/createObject
e.g.
{
"userData": [
{
"value": "someValue"
}
]
}
or you can set it after the server has been provisioned using these methods
http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/setUserMetadata
http://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/setUserMetadata
Basically the usermetadata are useful if you are going to use a post install script. The usermetadata value is not required to order a new server
take a look this article for examples:
http://sldn.softlayer.com/blog/jarteche/getting-started-user-data-and-post-provisioning-scripts

Related

Steps required to interract with IndexedDB via Dexie

Let's say I create a very simple datastore using the steps below:
var db = new Dexie('MyDatabase');
db.version(1).stores({ friends: 'name, age' });
db.friends.add({ name: 'Camilla', age: 25 });
Now, let’s say the user closes their browser and comes back a day later and we need to query the data that we already saved in a datastore that should already exist. Do I need to include both line 1 and line 2 each time before I query the datastore or insert new rows? I’m confused about when I’m required to execute line 2 – is it basically before I do anything to/with the datastore?
You would normally provide the db.version(x).stores({...}) each time you open the database, no matter if it needs to be created, upgraded or just being opened. By providing this info, you will get immediate access to your tables directly on the db object (accessing for example db.friends.toArray() without waiting for db.open() to finish) as samplified below:
var db = new Dexie("friendsDB");
db.version(1).stores({friends: 'id, name'});
// Here you can just access db.friends without waiting for db.open()
db.friends.toArray()
.then(friends => console.table(friends))
.catch(err => console.error(err));
However, it is also possible to open a database dynamically - that is, open an exising database without knowing its tables or indexes. To do that, you just omit the version().stores() part. Just be aware that you wont be able to access tables directly on the db instance and you don't get the magic auto-creation of the database. Tables meed to be accessed through the tables property and table() method, and only after db.open() has completed.
new Dexie("friendsDB").open().then(db => {
console.log("Table names: " + db.tables.map(t => t.name));
return db.table("friends").toArray();
}).then(friends => {
console.table(friends);
}).catch(err => console.error(err));

Designing a Firebase based scalable feed model

Question :
How to design a social network "feed" with Firebase as backend, that scales ?
Possible answers :
"MVP" solution is to design a feeds root child, one for each user, and append any new post from the followed user in every follower's feeds.
users
user1
name: bob
user2
name: alice
follows:
user1: true
posts
post1
author: user1
text: 'Hi there'
feeds
user2
post1: true
This works well, and is demoed in the Firefeed project. But it does not scale well : if Katy Perry wants to post something, her mobile phone will have to write to millions of feed.
Hence the solution reported in this SO question to delegate this operation to a server based process.
My problem is, Firebase is a "no-backend" solution, and this is the main reason why I use it, so I'd like to make sure there is absolutely no chance of implementing this feature without a server.
What if the feeds child is removed in the above schema ?
Then do this :
baseRef.child('posts')
.orderBy('author')
.whereIn(baseRef.child('users/user2/follows').keys())
Unfortunately, whereIn does not exists in Firebase API, nor subqueries :(
Any other model structure possible without the need of a server ?
Thanks
Firebase guys kinda replied on their blog : https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html
The post is about "Data fanning" (spreading items across many nodes in one atomic write operation).
The technique greatly addresses the feed model of the original question
The post actually contains example code for implementing it :
Function for creating the fannout object (actually a simple object with keys being API endpoints to be written)
function fanoutPost({ uid, followersSnaphot, post }) {
// Turn the hash of followers to an array of each id as the string
var followers = Object.keys(followersSnaphot.val());
var fanoutObj = {};
// write to each follower's timeline
followers.forEach((key) => fanoutObj['/timeline/' + key] = post);
return fanoutObj;
}
And the logic using this function :
var followersRef = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/followers');
var followers = {};
followersRef.on('value', (snap) => followers = snap.val());
var btnAddPost = document.getElementById('btnAddPost');
var txtPostTitle = document.getElementById('txtPostTitle');
btnAddPost.addEventListener(() => {
// make post
var post = { title: txtPostTitle.value };
// make fanout-object
var fanoutObj = fanoutPost({
uid: followersRef.getAuth().uid,
followers: followers,
post: post
});
// Send the object to the Firebase db for fan-out
rootRef.update(fanoutObj);
});
Note: this is way more scalable than a loop writing each time in one follower feed. However, it could nevertheless be insufficient for millions of followers. In that case, it would be safer to trust a server operation making several writes. I think client-side can be used for up to a few hundreds followers, which is the average number of followers on social media. (This needs to be verified by testing though)

Difficulty accessing entire hash in ruby with data pulled from api

I'm currently trying to pull data via the Yelp API, and can only seem to access half of the hash.
This code:
client = Yelp::Client.new
include Yelp::V2::Search::Request
request = Location.new(
:city => 'Melbourne',
:limit => 1) response = client.search(request)
puts response
Will output the full hash of
{"region"=>{"span"=>{"latitude_delta"=>0.0, "longitude_delta"=>0.0},
"center"=>{"latitude"=>28.0772451, "longitude"=>-80.6045478}},
"total"=>2324, "businesses"=>[{"is_claimed"=>false, "rating"=>4.5,
"mobile_url"=>"http://m.yelp.com/biz/el-ambia-cubano-melbourne",
"rating_img_url"=>"http://s3-media2.fl.yelpassets.com/assets/2/www/img/99493c12711e/ico/stars/v1/stars_4_half.png",
"review_count"=>168, "name"=>"El Ambia Cubano",
"snippet_image_url"=>"http://s3-media1.fl.yelpassets.com/photo/NgfGcZGdYlhTO18p8Shqrw/ms.jpg",
"rating_img_url_small"=>"http://s3-media2.fl.yelpassets.com/assets/2/www/img/a5221e66bc70/ico/stars/v1/stars_small_4_half.png",
"url"=>"http://www.yelp.com/biz/el-ambia-cubano-melbourne",
"phone"=>"3213278389", "snippet_text"=>"4.5 stars to me - rounded up
because the kids liked it too.\n\nWent here for lunch based mostly on
yelp reviews. Rest of my crew voted against Indian or Thai....",
"image_url"=>"http://s3-media3.fl.yelpassets.com/bphoto/pnZSlPiBDl1bS9w7saOAZA/ms.jpg",
"categories"=>[["Cuban", "cuban"]],
"display_phone"=>"+1-321-327-8389",
"rating_img_url_large"=>"http://s3-media4.fl.yelpassets.com/assets/2/www/img/9f83790ff7f6/ico/stars/v1/stars_large_4_half.png",
"id"=>"el-ambia-cubano-melbourne", "is_closed"=>false,
"location"=>{"city"=>"Melbourne", "display_address"=>["950 E Melbourne
Ave", "Melbourne, FL 32901"], "geo_accuracy"=>8.0,
"postal_code"=>"32901", "country_code"=>"US", "address"=>["950 E
Melbourne Ave"], "coordinate"=>{"latitude"=>28.0771809,
"longitude"=>-80.6044922}, "state_code"=>"FL"}}]}
I can access the region info by using
puts response["region"]
But I can't seem to access the rest of the hash? I'm specifically trying to extract the business name. What am I missing and need to do to access the entire hash?
businesses seems to be an array. Something like
response["businesses"][0]["name"]
Will retrive the name of the first business

How can I change the column name of an existing Class in the Parse.com Web Browser interface?

I couldn't find a way to change a column name, for a column I just created, either the browser interface or via an API call. It looks like all object-related API calls manipulate instances, not the class definition itself?
Anyone know if this is possible, without having to delete and re-create the column?
This is how I did it in python:
import json,httplib,urllib
connection = httplib.HTTPSConnection('api.parse.com', 443)
params = urllib.urlencode({"limit":1000})
connection.connect()
connection.request('GET', '/1/classes/Object?%s' % params, '', {
"X-Parse-Application-Id": "yourID",
"X-Parse-REST-API-Key": "yourKey"
})
result = json.loads(connection.getresponse().read())
objects = result['results']
for object in objects:
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
objectId = object['objectId']
objectData = object['data']
connection.request('PUT', ('/1/classes/Object/%s' % objectId), json.dumps({
"clonedData": objectData
}), {
"X-Parse-Application-Id": "yourID",
"X-Parse-REST-API-Key": "yourKEY",
"Content-Type": "application/json"
})
This is not optimized - you can batch 50 of the processes together at once, but since I'm just running it once I didn't do that. Also since there is a 1000 query limit from parse, you will need to do run the load multiple times with a skip parameter like
params = urllib.urlencode({"limit":1000, "skip":1000})
From this Parse forum answer : https://www.parse.com/questions/how-can-i-rename-a-column
Columns cannot be renamed. This is to avoid breaking an existing app.
If your app is still under development, you can just query for all the
objects in your class and copy the value of the old column to the new
column. The REST API is very useful for this. You may them drop the
old column in the Data Browser
Hope it helps
Yes, it's not a feature provided by Parse (yet). But there are some third party API management tools that you can use to rename the fields in the response. One free tool is called apibond.com
It's a work around, but I hope it helps

Checking if specific user is online through php session variable

I'm currently trying to display all online users on my webpage using the php session variables. To do this, whenever a user logs in or out, a column in a database gets set to "online" or "offline".. However this doesn't entirely work since the database doesn't get updated when the user closes their browser (and therefor destroys the session).
So is there another way of checking if a certain sessionid is set??
Currently I am setting the session like this:
session_start();
$_SESSION['username']="Example Username";
To check from the current users page if there is a session variable set we can simply use:
if(isset($_SESSION['username']))
{
//username is set
}
But if we need to check if a specific user is online, how do we get for instance an array of all the session variables that have been set? e.g.
//Get all $_SESSION['username'] vars
//loop through array and check for specific $_SESSION
for($i=0; ... )
{
if( $_SESSION['username'][$i] == "User 1" )
{
//do something
}
}
From all that I've read so far, there doesn't seem to be a way to get an array of all sessions on your page..
So is there a better way of doing it, e.g. how do facebook, twitter, etc handle this stuff?
Thanks for your help!
One solution is to store a timestamp in your database in addition to the online/offline flag that records the last time a user accessed any of your website resources. Then you might just consider them offline after 15 minutes or some other constant value.
The other solution is to play with the callbacks here http://php.net/manual/en/function.session-set-save-handler.php where I think you can handle the gc callback and set the offline flag in your database.
If you search on that page for class SessionDB or go here it looks like somebody has implemented some version of this already in a custom class!
you can use a simple update query
for example you have a table users and in that you have a column called status(online/offline)
on your login.php use
<?php
//your user verification code
if(variable that holds your sql query){
$user_status=('UPDATE user SET status= online WHERE email="'your user email selector'")
}
then on the logout do a similar script just change the online value to offline
You could try this:
foreach ($_SESSION as $sessionKey => $sessionValue)
{
if( $sessionKey == 'username' ) && ( $sessionValue == 'User 1' )
{
//do something
}
}

Resources