/// <summary>
 /// Execute SP with return value as non Enumerable
 /// </summary>
 /// <param name="transit">return value as reference value</param>
 /// <param name="command">executive command</param>
 private void ExecuteWithSingleReturnValue(TransitObject transit, IDbCommand command)
 {
     command.Prepare();
     if (transit.ReturnType.IsClass && transit.ReturnType != typeof(string))
     {
         _queryTime?.Start();
         using (var reader = command.ExecuteReader())
         {
             _queryTime?.Stop();
             int columns  = reader.FieldCount;
             var accessor = TypeAccessor.Create(transit.ReturnType);
             foreach (var record in reader.ToRecord())
             {
                 var item = accessor.CreateNew();
                 ExtractObject(columns, item, accessor, record);
                 transit.ReturnObject = item;
                 break;
             }
         }
     }
     else
     {
         _queryTime?.Start();
         transit.ReturnObject = command.ExecuteScalar();
         _queryTime?.Stop();
     }
 }
        /// <summary>
        /// Execute if TVP is activated
        /// </summary>
        /// <param name="transit">return value as reference value</param>
        /// <param name="command">executive command</param>
        private void ExecuteTvp(TransitObject transit, IDbCommand command)
        {
            PrepareExecute(transit, command);
            foreach (var item in transit.Parameters)
            {
                CreateNewDataTableParameter(item.Key.Name, command, item.Value);
            }

            // if transit is List execute reader
            if (transit.ReturnType.IsArray || (true.In(transit.ReturnType.IsInterface, transit.ReturnType.IsAbstract) && typeof(IEnumerable).IsAssignableFrom(transit.ReturnType)))
            {
                TypeAccessor accessor = TypeAccessor.Create(transit.ReturnType.IsArray ? transit.ReturnType.GetElementType() : transit.ReturnType.GenericTypeArguments[0]);
                var          items    = transit.ReturnObject as ArrayList;
                ExecuteReaderToList(items, accessor, command);
                transit.ReturnObject = items.ToArray();
            }
            else if (transit.ReturnObject is IList)
            {
                var items    = (IList)transit.ReturnObject;
                var accessor = TypeAccessor.Create(transit.ReturnType.GenericTypeArguments[0]);
                ExecuteReaderToList(items, accessor, command);
            }
            else if (transit.ReturnType != typeof(void))
            {
                // execute scalar. Can be Struct too
                ExecuteWithSingleReturnValue(transit, command);
            }
            else
            {
                ExecuteNonQuery(command);
            }
        }
        /// <summary>
        /// Initialize some vital properties for SP execution
        /// </summary>
        /// <param name="transit">Placeholder for internal parameter use</param>
        /// <param name="methodInfo">Method Information</param>
        /// <param name="parameters">Parameters from execution code</param>
        private void PrepareInitialization(TransitObject transit, MethodInfo methodInfo, object[] parameters)
        {
            transit.ReturnType = methodInfo.ReturnType;
            // fill parameter informations
            transit.Parameters = new Dictionary <ParameterInfo, object>();
            int index = 0;

            foreach (var item in methodInfo.GetParameters())
            {
                transit.Parameters.Add(item, parameters[index++]);
            }

            transit.CommandText = transit.ExtendedInformations?.CreateCall(methodInfo.Name) ?? methodInfo.Name;
            var retType = transit.ReturnType;

            if (retType.In(typeof(void), typeof(string)) == false)
            {
                if (retType.IsArray || typeof(IEnumerable).IsAssignableFrom(retType))
                {
                    transit.ReturnObject = new ArrayList();
                }
                else
                {
                    transit.ReturnObject = Activator.CreateInstance(transit.ReturnType);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Get an object with Google Pay API for Passes REST API
        /// See https://developers.google.com/pay/passes/reference/v1/transitobject/get
        /// </summary>
        /// <param name="id">id of the object</param>
        /// <returns>Object</returns>
        public TransitObject getTransitObject(string id)
        {
            TransitObject response = null;
            // Uses the Google Pay API for Passes C# client lib to get a Transit object
            // check the devsite for newest client lib: https://developers.google.com/pay/passes/support/libraries#libraries
            // check reference API to see the underlying REST call:
            // https://developers.google.com/pay/passes/reference/v1/transitobject/get
            WalletobjectsService service = new WalletobjectsService(new Google.Apis.Services.BaseClientService.Initializer()
            {
                HttpClientInitializer = this.credential
            });

            try
            {
                response = service.Transitobject.Get(id).Execute();
            }
            catch (Google.GoogleApiException ge)
            {
                System.Console.WriteLine(">>>> [START] Google Server Error response:");
                System.Console.WriteLine(ge.Message);
                System.Console.WriteLine(">>>> [END] Google Server Error response\n");
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
            }
            return(response);
        }
Exemplo n.º 5
0
 public void addTransitObject(TransitObject transitObject)
 {
     if (this.payload.transitObjects == null)
     {
         this.payload.transitObjects = new List <TransitObject>();
     }
     this.payload.transitObjects.Add(transitObject);
 }
Exemplo n.º 6
0
        public TransitObject Retrieve(int id)
        {
            string method = string.Format("Get{0}ById", ObjectType);

            object[]      args = { Ticket, id };
            TransitObject to   = (TransitObject)Blog.GetType().InvokeMember(method, BindingFlags.InvokeMethod, null, Blog, args);

            Console.WriteLine(string.Format("{0}: {1} -> {2}: {3}", method, id, to.ToString(), to.Id));
            return(to);
        }
 /// <summary>
 /// Concrete implementation for List handler
 /// </summary>
 /// <param name="transit">return value as reference value</param>
 /// <param name="command">executive command</param>
 private void Execute(TransitObject transit, IDbCommand command)
 {
     // can only set if TVP is activated
     if (_operations.HasFlag(RepositoryOperations.UseTableValuedParameter))
     {
         ExecuteTvp(transit, command);
     }
     else
     {
         ExecuteSingleItem(transit, command);
     }
 }
        /// <summary>
        /// Pre-Execution Process that allow create stored Procedure parameters
        /// </summary>
        /// <param name="transit">placeholder that contains sp parameters</param>
        /// <param name="command">command we used to store parameters</param>
        private void PrepareExecute(TransitObject transit, IDbCommand command)
        {
            Type refString = Type.GetType("System.String&");

            // fill the parameters
            foreach (var item in transit.Parameters)
            {
                if ((item.Value is ICollection) || typeof(ICollection).IsAssignableFrom(item.Key.ParameterType))
                {
                    continue;
                }
                //.Where(a => a.Value.GetType().GenericTypeArguments.Length == 0)
                ParameterInfo      pi        = item.Key;
                ParameterDirection direction = ParameterDirection.Input;
                if (pi.IsOut && pi.IsIn == false)
                {
                    direction = ParameterDirection.Output;
                }
                else if (pi.ParameterType.IsByRef)
                {
                    direction = ParameterDirection.InputOutput;
                }

                var type = item.Value?.GetType() ?? pi.ParameterType;

                if (type.IsClass && type.In(typeof(string), refString) == false)
                {
                    //remove by ref value from type
                    if (type.Name.EndsWith("&"))
                    {
                        type = type.Assembly.GetType(type.FullName.Replace("&", ""));
                    }
                    CreateRefScalarVariable(transit, item.Key.Position, type, item.Value, command, direction);
                }
                else
                {
                    int?size = null;

                    if (pi.ParameterType.In(typeof(string), refString))
                    {
                        size = -1;
                    }
                    var parameter = command.AddParameter(pi.Name, item.Value, direction, size: size);

                    if (pi.IsOut || pi.ParameterType.IsByRef)
                    {
                        transit.Outputs.Add(pi, parameter);
                    }
                }
            }
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = transit.CommandText;
        }
        /// <summary>
        /// Generate a transit object
        /// See https://developers.google.com/pay/passes/reference/v1/transitobject
        /// </summary>
        /// <param name="objectId"> the unique identifier for a object</param>
        /// <returns>the inserted transit object</returns>
        public TransitObject makeTransitObjectResource(string objectId, string classId)
        {
            // Define the resource representation of the Object
            // values should be from your DB/services; here we hardcode information
            // below defines an transit object. For more properties, check:
            //// https://developers.google.com/pay/passes/reference/v1/transitobject/insert
            //// https://developers.google.com/pay/passes/guides/pass-verticals/transit-passes/design

            // There is a client lib to help make the data structure. Newest client is on
            // devsite:
            //// https://developers.google.com/pay/passes/support/libraries#libraries
            TransitObject payload = new TransitObject();

            //required fields
            payload.Id        = objectId;
            payload.ClassId   = classId;
            payload.State     = "active";
            payload.TripType  = "oneWay";
            payload.TicketLeg = new TicketLeg()
            {
                OriginStationCode = "LA",
                OriginName        = new LocalizedString()
                {
                    DefaultValue = new TranslatedString()
                    {
                        Language = "en-US",
                        Value    = "LA Transit Center"
                    }
                },
                DestinationStationCode = "SFO",
                DestinationName        = new LocalizedString()
                {
                    DefaultValue = new TranslatedString()
                    {
                        Language = "en-US",
                        Value    = "SFO Transit Center"
                    }
                },
                DepartureDateTime = "2020-04-12T16:20:50.52Z",
                ArrivalDateTime   = "2020-04-12T20:20:50.52Z"
            };
            //optional fields. See design and reference api for more
            payload.Barcode = new Barcode()
            {
                Type          = "qrCode",
                Value         = "1234abc",
                AlternateText = "1234abc"
            };

            return(payload);
        }
Exemplo n.º 10
0
        public void TestCrud()
        {
            int id    = Create();
            int count = Count();

            Assert.IsTrue(count > 0);
            TransitObject to = Retrieve(id);

            Assert.AreEqual(to.Id, id);
            TransitInstance.Id = id;
            int id2 = Create();

            Assert.AreEqual(id, id2);
            Delete();
        }
        public void TestInsertTransitClassAndObject()
        {
            RestMethods         restMethods         = RestMethods.getInstance();
            ResourceDefinitions resourceDefinitions = ResourceDefinitions.getInstance();
            VerticalType        verticalType        = Services.VerticalType.TRANSIT;
            Config        config         = Config.getInstance();
            string        UUID           = Guid.NewGuid().ToString();
            string        classUid       = $"{verticalType.ToString()}_CLASS_{UUID}";
            string        classId        = $"{config.getIssuerId()}.{classUid}";
            string        UUIDobj        = Guid.NewGuid().ToString();
            string        objectUid      = $"{verticalType.ToString()}_OBJECT_{UUIDobj}";
            string        objectId       = $"{config.getIssuerId()}.{objectUid}";
            TransitClass  classResponse  = restMethods.insertTransitClass(resourceDefinitions.makeTransitClassResource(classId));
            TransitObject objectResponse = restMethods.insertTransitObject(resourceDefinitions.makeTransitObjectResource(objectId, classId));

            Assert.NotNull(classResponse);
            Assert.NotNull(objectResponse);
        }
        private void CreateRefScalarVariable(TransitObject transit, int index, Type type, object data, IDbCommand command, ParameterDirection direction)
        {
            var tAccessor             = TypeAccessor.Create(type);
            RefScalarVariables result = null;

            if (direction == ParameterDirection.InputOutput || direction == ParameterDirection.Output)
            {
                transit.Refernces.Add(result = new RefScalarVariables
                {
                    Direction = direction,
                    Index     = index,
                    Value     = data,
                    Accessor  = tAccessor
                });
            }
            foreach (var item in tAccessor.GetMembers())
            {
                object value     = direction == ParameterDirection.Output ? null : tAccessor[data, item.Name];
                var    parameter = command.AddParameter(item.Name, value, direction);
                result?.Parameters.Add(parameter);
            }
        }
Exemplo n.º 13
0
        static async Task Main(string[] args)
        {
            var flows = new[]
            {
                CreateFlow(),
                CreateFlow(),
                CreateFlow(),
                CreateFlow(),
                CreateFlow()
            };

            while (true)
            {
                var input = Console.ReadLine();

                if (!int.TryParse(input, out var times))
                {
                    continue;
                }

                var sw = Stopwatch.StartNew();

                Parallel.ForEach(flows, async flow =>
                {
                    for (int i = 0; i < times; i++)
                    {
                        var obj    = new TransitObject();
                        obj.Number = i;
                        await flow.Execute(obj);
                    }
                });

                sw.Stop();

                Console.WriteLine("Elapsed: {0}", sw.ElapsedMilliseconds);
            }
        }
        /// <summary>
        /// Execute Single Item, when TVP is not available but list is given
        /// </summary>
        /// <param name="transit">return value as reference value</param>
        /// <param name="command">executive command</param>
        private void ExecuteSingleItem(TransitObject transit, IDbCommand command)
        {
            // do not allow cartesian product
            var collection = transit.Parameters.Where(a => a.Value is ICollection).Select(a => new KeyValuePair <ParameterInfo, ICollection>(a.Key, (ICollection)a.Value)).ToList();

            if (_operations.HasFlag(RepositoryOperations.UseTableValuedParameter) == false)
            {
                if (collection.Count > 1)
                {
                    throw new NotSupportedException(nameof(Resources.DA004));
                }
            }
            PrepareExecute(transit, command);
            bool isArrayOrEnumerable = transit.ReturnType.IsArray || (typeof(IEnumerable).IsAssignableFrom(transit.ReturnType) && transit.ReturnType != typeof(string));

            // if transit is List execute reader
            if (transit.ReturnObject is IList || isArrayOrEnumerable)
            {
                IList        items    = null;
                TypeAccessor accessor = null;
                if (transit.ReturnType.IsArray)
                {
                    accessor = TypeAccessor.Create(transit.ReturnType.GetElementType());
                }
                else
                {
                    accessor = TypeAccessor.Create(transit.ReturnType.GenericTypeArguments[0]);
                }
                items = (IList)transit.ReturnObject;

                if (collection.Count > 0)
                {
                    var          first       = collection.First();
                    var          valueType   = first.Value.GetType();
                    var          genericType = valueType.IsArray ? valueType.GetElementType() : valueType.GenericTypeArguments[0];
                    TypeAccessor listType    = genericType.IsClass && genericType != typeof(string) ? TypeAccessor.Create(genericType) : null;

                    foreach (var item in first.Value)
                    {
                        CreateRefScalarVariable(first.Key.Name, item, listType, command);
                        ExecuteReaderToList(items, accessor, command);
                    }
                }
                else
                {
                    ExecuteReaderToList(items, accessor, command);
                }

                if (transit.ReturnType.IsArray)
                {
                    transit.ReturnObject = ((ArrayList)items).ToArray();
                }
            }
            // execute scalar. Can be Struct too
            else if (transit.ReturnType != typeof(void))
            {
                ExecuteWithSingleReturnValue(transit, command);
            }
            // ExecuteNonQuery
            else
            {
                if (collection.Count > 0)
                {
                    var          genericType = collection.First().Value.GetType().GenericTypeArguments[0];
                    TypeAccessor listType    = genericType.IsClass && genericType != typeof(string) ? TypeAccessor.Create(genericType) : null;

                    foreach (var item in collection.First().Value)
                    {
                        CreateRefScalarVariable(genericType.Name, item, listType, command);
                        ExecuteNonQuery(command);
                    }
                }
                else
                {
                    ExecuteNonQuery(command);
                }
            }
        }
        /// <summary>Processes an invocation on a target.</summary>
        /// <param name="target">The target object.</param>
        /// <param name="methodInfo">The method information.</param>
        /// <param name="parameters">The parameter values.</param>
        /// <returns>The return value.</returns>
        public object Invoke(object target, MethodInfo methodInfo, object[] parameters)
        {
            Object result = null;

            if (methodInfo.Name == nameof(IRepository.Dispose))
            {
                _cache.Clear();
                _connection?.Dispose();
                _connection = null;
            }
            else if (methodInfo.Name == $"set_{nameof(IRepository.ConnectionStringSettings)}")
            {
                string newSetting = parameters[0].ToString();
                if (newSetting != _connectionStringSettings)
                {
                    _connection?.Dispose();
                    _connection = null;
                    _settings   = null;
                    _connectionStringSettings = newSetting;
                }
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.ConnectionStringSettings)}")
            {
                result = _connectionStringSettings;
            }
            else if (methodInfo.Name == $"set_{nameof(IRepository.Connection)}")
            {
                _connection = parameters[0] as IDbConnection;
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.Connection)}")
            {
                result = Connection;
            }
            else if (methodInfo.Name == $"set_{nameof(IRepository.TvpNameConvension)}")
            {
                _tvpNameConvention = parameters[0].ToString();
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.TvpNameConvension)}")
            {
                result = _tvpNameConvention;
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.QueryExecutionTime)}")
            {
                result = _queryTime?.Elapsed;
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.TotalExecutionTime)}")
            {
                result = _totalTime?.Elapsed;
            }
            else if (methodInfo.Name == $"set_{nameof(IRepository.Operations)}")
            {
                _operations = (RepositoryOperations)parameters[0];
                InitWatches();
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.Operations)}")
            {
                result = _operations;
            }
            else if (methodInfo.Name == $"get_{nameof(IRepository.ExtendedInformationCacheSize)}")
            {
                result = _cache.Count;
            }
            else
            {
                InitWatches();
                _totalTime?.Reset();
                _queryTime?.Reset();
                _totalTime?.Start();
                try
                {
                    var transit = new TransitObject
                    {
                        ExtendedInformations = GetExtendedInformation(methodInfo)
                    };
                    PrepareInitialization(transit, methodInfo, parameters);
                    var connection = Connection;
                    using (var command = connection.CreateCommand())
                    {
                        command.Connection = connection;
                        Execute(transit, command);
                    }

                    // write output parameters
                    foreach (var item in transit.Outputs)
                    {
                        parameters[item.Key.Position] = item.Value.Value;
                    }

                    foreach (var item in transit.Refernces)
                    {
                        item.WriteBack(parameters);
                    }

                    result = transit.ReturnObject;
                }
                catch when(ExceptionFilter())
                {
                }
                _totalTime?.Stop();
            }
            return(result);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Generates a signed "fat" JWT.
        /// No REST calls made.
        /// Use fat JWT in JS web button.
        /// Fat JWT is too long to be used in Android intents.
        /// Possibly might break in redirects.
        /// </summary>
        /// <param name="verticalType"> pass type to created</param>
        /// <param name="classId">the unique identifier for the class</param>
        /// <param name="objectId">the unique identifier for the object</param>
        /// <returns></returns>
        public string makeFatJwt(VerticalType verticalType, string classId, string objectId)
        {
            ResourceDefinitions resourceDefinitions = ResourceDefinitions.getInstance();
            RestMethods         restMethods         = RestMethods.getInstance();
            // create JWT to put objects and class into JSON Web Token (JWT) format for Google Pay API for Passes
            Jwt googlePassJwt = new Jwt();

            // get class definition, object definition and see if Ids exist. for a fat JWT, first time a user hits the save button, the class and object are inserted
            try
            {
                switch (verticalType)
                {
                case VerticalType.OFFER:
                    OfferClass  offerClass  = resourceDefinitions.makeOfferClassResource(classId);
                    OfferObject offerObject = resourceDefinitions.makeOfferObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    OfferClass  classResponse  = restMethods.getOfferClass(classId);
                    OfferObject objectResponse = restMethods.getOfferObject(objectId);
                    // check responses
                    if (!(classResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(objectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(classResponse is null) && objectResponse.ClassId != offerObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({objectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({offerObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addOfferClass(offerClass);
                    googlePassJwt.addOfferObject(offerObject);
                    break;

                case VerticalType.LOYALTY:
                    LoyaltyClass  loyaltyClass  = resourceDefinitions.makeLoyaltyClassResource(classId);
                    LoyaltyObject loyaltyObject = resourceDefinitions.makeLoyaltyObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    LoyaltyClass  loyaltyClassResponse  = restMethods.getLoyaltyClass(classId);
                    LoyaltyObject loyaltyObjectResponse = restMethods.getLoyaltyObject(objectId);
                    // check responses
                    if (!(loyaltyClassResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(loyaltyObjectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(loyaltyClassResponse is null) && loyaltyObjectResponse.ClassId != loyaltyObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({loyaltyObjectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({loyaltyObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addLoyaltyClass(loyaltyClass);
                    googlePassJwt.addLoyaltyObject(loyaltyObject);
                    break;

                case VerticalType.EVENTTICKET:
                    EventTicketClass  eventTicketClass  = resourceDefinitions.makeEventTicketClassResource(classId);
                    EventTicketObject eventTicketObject = resourceDefinitions.makeEventTicketObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    EventTicketClass  eventTicketClassResponse  = restMethods.getEventTicketClass(classId);
                    EventTicketObject eventTicketObjectResponse = restMethods.getEventTicketObject(objectId);
                    // check responses
                    if (!(eventTicketClassResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(eventTicketObjectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(eventTicketClassResponse is null) && eventTicketObjectResponse.ClassId != eventTicketObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({eventTicketObjectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({eventTicketObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addEventTicketClass(eventTicketClass);
                    googlePassJwt.addEventTicketObject(eventTicketObject);
                    break;

                case VerticalType.FLIGHT:
                    FlightClass  flightClass  = resourceDefinitions.makeFlightClassResource(classId);
                    FlightObject flightObject = resourceDefinitions.makeFlightObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    FlightClass  flightClassResponse  = restMethods.getFlightClass(classId);
                    FlightObject flightObjectResponse = restMethods.getFlightObject(objectId);
                    // check responses
                    if (!(flightClassResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(flightObjectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(flightClassResponse is null) && flightObjectResponse.ClassId != flightObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({flightObjectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({flightObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addFlightClass(flightClass);
                    googlePassJwt.addFlightObject(flightObject);
                    break;

                case VerticalType.GIFTCARD:
                    GiftCardClass  giftCardClass  = resourceDefinitions.makeGiftCardClassResource(classId);
                    GiftCardObject giftCardObject = resourceDefinitions.makeGiftCardObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    GiftCardClass  giftCardClassResponse  = restMethods.getGiftCardClass(classId);
                    GiftCardObject giftCardObjectResponse = restMethods.getGiftCardObject(objectId);
                    // check responses
                    if (!(giftCardClassResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(giftCardObjectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(giftCardClassResponse is null) && giftCardObjectResponse.ClassId != giftCardObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({giftCardObjectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({giftCardObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addGiftCardClass(giftCardClass);
                    googlePassJwt.addGiftCardObject(giftCardObject);
                    break;

                case VerticalType.TRANSIT:
                    TransitClass  transitClass  = resourceDefinitions.makeTransitClassResource(classId);
                    TransitObject transitObject = resourceDefinitions.makeTransitObjectResource(objectId, classId);
                    System.Console.WriteLine("\nMaking REST call to get class and object to see if they exist.");
                    TransitClass  transitClassResponse  = restMethods.getTransitClass(classId);
                    TransitObject transitObjectResponse = restMethods.getTransitObject(objectId);
                    // check responses
                    if (!(transitClassResponse is null))
                    {
                        System.Console.WriteLine($"classId: {classId} already exists.");
                    }
                    if (!(transitObjectResponse is null))
                    {
                        System.Console.WriteLine($"objectId: {objectId} already exists.");
                    }
                    if (!(transitClassResponse is null) && transitObjectResponse.ClassId != transitObject.ClassId)
                    {
                        System.Console.WriteLine($"the classId of inserted object is ({transitObjectResponse.ClassId}). " +
                                                 $"It does not match the target classId ({transitObject.ClassId}). The saved object will not " +
                                                 "have the class properties you expect.");
                    }
                    // need to add both class and object resource definitions into JWT because no REST calls made to pre-insert
                    googlePassJwt.addTransitClass(transitClass);
                    googlePassJwt.addTransitObject(transitObject);
                    break;
                }
                // return "fat" JWT. Try putting it into JS web button
                // note button needs to be rendered in local web server who's domain matches the ORIGINS
                // defined in the JWT. See https://developers.google.com/pay/passes/reference/s2w-reference
                return(googlePassJwt.generateSignedJwt());
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine(e.Message);
                return(null);
            }
        }